38 if(
lookup(bit->find(ID_type).get(ID_identifier)).base_name == base_name)
40 identifier=bit->find(ID_type).get(ID_identifier);
51 if(expr.
id()==ID_cpp_name)
53 else if(expr.
id()==
"cpp-this")
55 else if(expr.
id()==
"pointer-to-member")
57 else if(expr.
id()==
"new_object")
63 else if(expr.
id()==
"explicit-typecast")
65 else if(expr.
id()==
"explicit-constructor-call")
70 std::cerr <<
"E: " << expr.
pretty() <<
'\n';
71 std::cerr <<
"cpp_typecheckt::typecheck_expr_main got nil\n";
75 else if(expr.
id()==ID_code)
78 std::cerr <<
"E: " << expr.
pretty() <<
'\n';
79 std::cerr <<
"cpp_typecheckt::typecheck_expr_main got code\n";
83 else if(expr.
id()==ID_symbol)
87 std::cerr <<
"E: " << expr.
pretty() <<
'\n';
88 std::cerr <<
"cpp_typecheckt::typecheck_expr_main got symbol\n";
91 else if(expr.
id()==
"__is_base_of")
105 if(base.
id()!=ID_struct || deriv.
id()!=ID_struct)
118 else if(expr.
id()==ID_msc_uuidof)
124 expr.
set(ID_C_lvalue,
true);
126 else if(expr.
id()==ID_noexcept)
131 else if(expr.
id()==ID_initializer_list)
133 expr.
type().
id(ID_initializer_list);
154 error() <<
"error: lvalue to rvalue conversion" <<
eom;
165 error() <<
"error: array to pointer conversion" <<
eom;
176 error() <<
"error: function to pointer conversion" <<
eom;
187 error() <<
"error: lvalue to rvalue conversion" <<
eom;
198 error() <<
"error: array to pointer conversion" <<
eom;
209 error() <<
"error: function to pointer conversion" <<
eom;
214 if(expr.
op1().
get(ID_statement)==ID_throw &&
215 expr.
op2().
get(ID_statement)!=ID_throw)
217 else if(expr.
op2().
get(ID_statement)==ID_throw &&
218 expr.
op1().
get(ID_statement)!=ID_throw)
220 else if(expr.
op1().
type().
id()==ID_empty &&
226 error() <<
"error: bad types for operands" <<
eom;
258 else if(expr.
op1().
type().
id()==ID_array &&
285 error() <<
"error: types are incompatible.\n" 295 expr.
set(ID_C_lvalue,
true);
315 static_cast<const typet &
>(expr.
find(ID_type_arg));
317 if(type.
id()==ID_cpp_name)
329 if(symbol_expr.
id()!=ID_type)
335 else if(type.
id()==ID_array)
348 if(symbol_expr.
id()!=ID_type)
371 if(expr.
id()==ID_cpp_name)
373 else if(expr.
id()==ID_member)
378 else if(expr.
id()==ID_ptrmember)
386 std::string op_name=
"operator->";
396 cpp_name.
get_sub().back().set(ID_identifier, op_name);
397 cpp_name.
get_sub().back().add(ID_C_source_location)=
401 static_cast<const exprt &
>(
402 static_cast<const irept &
>(cpp_name));
408 exprt tmp(
"already_typechecked");
410 function_call.
swap(tmp);
412 expr.
op0().
swap(function_call);
434 if(t.
id()==ID_struct ||
435 t.
id() == ID_incomplete_struct ||
437 t.
id()==ID_c_enum || t.
id() == ID_c_enum_tag)
459 { ID_unary_minus,
"-" },
471 { ID_notequal,
"!=" },
472 { ID_dereference,
"*" },
473 { ID_ptrmember,
"->" },
484 else if(expr.
id()==ID_dereference &&
490 if(expr.
id()==
"explicit-typecast")
496 std::string op_name=std::string(
"operator")+
"("+
cpp_type2name(t)+
")";
505 cpp_name.
get_sub().back().set(ID_identifier, op_name);
509 bool found_in_struct=
false;
513 if(t0.id()==ID_struct)
521 for(struct_typet::componentst::const_iterator
522 it=components.begin();
523 it!=components.end();
526 if(!it->get_bool(ID_from_base) &&
527 it->get(ID_base_name) == op_name)
529 found_in_struct=
true;
539 exprt member(ID_member);
540 member.
add(ID_component_cpp_name)= cpp_name;
542 exprt tmp(
"already_typechecked");
551 for(exprt::operandst::const_iterator
553 it!=(expr).operands().end();
555 function_call.
arguments().push_back(*it);
560 if(expr.
id()==ID_ptrmember)
563 exprt tmp(
"already_typechecked");
570 expr.
swap(function_call);
579 if(expr.
id()==ID_dereference)
580 assert(!expr.
get_bool(ID_C_implicit));
582 std::string op_name=std::string(
"operator")+e->op_name;
587 cpp_name.
get_sub().back().set(ID_identifier, op_name);
588 cpp_name.
get_sub().back().add(ID_C_source_location)=
632 exprt member(ID_member);
633 member.
add(ID_component_cpp_name)=cpp_name;
635 exprt tmp(
"already_typechecked");
645 for(exprt::operandst::const_iterator
649 function_call.
arguments().push_back(*it);
674 static_cast<const exprt &
>(
675 static_cast<const irept &
>(cpp_name));
679 function_call.
arguments().push_back(*it);
683 if(expr.
id()==ID_ptrmember)
686 exprt tmp(
"already_typechecked");
708 error() <<
"address_of expects one operand" <<
eom;
717 error() <<
"expr not an lvalue" <<
eom;
724 assert(expr.
op0().
id()==ID_member);
727 address.
set(ID_C_implicit,
true);
731 if(expr.
op0().
id()==ID_address_of &&
738 if(args.size() > 0 && args[0].get(ID_C_base_name)==ID_this)
744 if(code_type.
get_bool(ID_C_is_virtual))
747 error() <<
"error: pointers to virtual methods" 748 <<
" are currently not implemented" <<
eom;
754 expr.
op0().
id() == ID_ptrmember && expr.
op0().
op0().
id() ==
"cpp-this")
781 if(
follow(exception_type).
id()==ID_empty)
784 error() <<
"cannot throw void" <<
eom;
789 expr.
set(ID_exception_list,
798 if(expr.
type().
id()==ID_array)
807 bool size_is_unsigned=(size.type().id()==ID_unsignedbv);
808 typet integer_type(size_is_unsigned?ID_unsignedbv:ID_signedbv);
812 expr.
set(ID_statement, ID_cpp_new_array);
827 expr.
set(ID_statement, ID_cpp_new);
834 object_expr.
set(ID_C_lvalue,
true);
837 exprt tmp(
"already_typechecked");
839 object_expr.swap(tmp);
843 exprt &initializer=
static_cast<exprt &
>(expr.
add(ID_initializer));
846 if(!initializer.
operands().empty() &&
847 expr.
get(ID_statement)==ID_cpp_new_array)
850 error() <<
"new with array type must not use initializer" <<
eom;
860 expr.
add(ID_initializer).
swap(code);
865 exprt &sizeof_expr=
static_cast<exprt &
>(expr.
add(ID_sizeof));
874 if(src.
id()==ID_comma)
912 if(expr.
type().
id()==ID_cpp_name)
923 if(symbol_expr.
id()==ID_type)
947 if(expr.
op0().
id()==ID_initializer_list)
956 exprt tmp(ID_compound_literal, expr.
type());
959 expr.
set(ID_C_lvalue,
true);
975 error() <<
"invalid explicit cast:\n" 986 error() <<
"explicit typecast expects 0 or 1 operands" <<
eom;
997 expr.
id(
"explicit-typecast");
1002 assert(expr.
type().
id()==ID_struct);
1017 error() <<
"`this' is not allowed here" <<
eom;
1025 assert(this_expr.
type().
id()==ID_pointer);
1036 error() <<
"delete expects one operand" <<
eom;
1042 if(statement==ID_cpp_delete)
1045 else if(statement==ID_cpp_delete_array)
1056 error() <<
"delete takes a pointer type operand, but got `" 1072 new_object.
set(ID_C_lvalue,
true);
1084 expr.
set(ID_destructor, destructor_code);
1091 std::cout <<
"E: " << expr.pretty() <<
'\n';
1103 error() <<
"error: member operator expects one operand" <<
eom;
1119 exprt tmp(
"cpp_dummy_destructor");
1130 if(followed_op0_type.id()==ID_incomplete_struct ||
1131 followed_op0_type.id()==ID_incomplete_union)
1134 error() <<
"error: member operator got incomplete type " 1135 <<
"on left hand side" <<
eom;
1139 if(followed_op0_type.id()!=ID_struct &&
1140 followed_op0_type.id()!=ID_union)
1143 error() <<
"error: member operator requires struct/union type " 1144 <<
"on left hand side but got `" 1172 if(symbol_expr.
id()==ID_dereference)
1174 assert(symbol_expr.
get_bool(ID_C_implicit));
1176 symbol_expr.
swap(tmp);
1179 assert(symbol_expr.
id()==ID_symbol ||
1180 symbol_expr.
id()==ID_member ||
1181 symbol_expr.
id()==ID_constant);
1187 if(symbol_expr.
id()==ID_symbol)
1189 if(symbol_expr.
type().
id()==ID_code &&
1190 symbol_expr.
type().
get(ID_return_type)==ID_constructor)
1193 error() <<
"error: member `" 1194 <<
lookup(symbol_expr.
get(ID_identifier)).base_name
1195 <<
"' is a constructor" <<
eom;
1207 error() <<
"error: `" 1208 << symbol_expr.
get(ID_identifier)
1209 <<
"' is not static member " 1210 <<
"of class `" <<
to_string(type) <<
"'" 1219 else if(symbol_expr.
id()==ID_constant)
1225 const irep_idt component_name=symbol_expr.
get(ID_component_name);
1227 expr.
remove(ID_component_cpp_name);
1228 expr.
set(ID_component_name, component_name);
1231 const irep_idt &component_name=expr.
get(ID_component_name);
1233 assert(component_name!=
"");
1254 error() <<
"error: member `" << component_name
1256 <<
"' not found" <<
eom;
1262 if(expr.
type().
id()==ID_code)
1265 symbol_tablet::symbolst::const_iterator it=
1270 if(it->second.value.id()==
"cpp_not_typechecked")
1279 assert(expr.
id()==ID_ptrmember);
1284 error() <<
"error: ptrmember operator expects one operand" <<
eom;
1293 error() <<
"error: ptrmember operator requires pointer type " 1294 <<
"on left hand side, but got `" 1304 op.
id(ID_dereference);
1321 error() <<
"cast expressions expect one operand" <<
eom;
1331 f_op.
get_sub().front().get(ID_identifier);
1333 if(f_op.
get_sub().size()!=2 ||
1334 f_op.
get_sub()[1].id()!=ID_template_args)
1337 error() <<
id <<
" expects template argument" <<
eom;
1341 irept &template_arguments=f_op.
get_sub()[1].add(ID_arguments);
1343 if(template_arguments.
get_sub().size()!=1)
1346 error() <<
id <<
" expects one template argument" <<
eom;
1350 irept &template_arg=template_arguments.
get_sub().front();
1352 if(template_arg.
id()!=ID_type &&
1353 template_arg.
id()!=
"ambiguous")
1356 error() <<
id <<
" expects a type as template argument" <<
eom;
1361 template_arguments.
get_sub().front().add(ID_type));
1368 if(
id==ID_const_cast)
1373 error() <<
"type mismatch on const_cast:\n" 1380 else if(
id==ID_dynamic_cast)
1385 error() <<
"type mismatch on dynamic_cast:\n" 1392 else if(
id==ID_reinterpret_cast)
1397 error() <<
"type mismatch on reinterpret_cast:\n" 1404 else if(
id==ID_static_cast)
1409 error() <<
"type mismatch on static_cast:\n" 1419 expr.
swap(new_expr);
1429 if(expr.
get_sub().size()==1 &&
1430 expr.
get_sub()[0].id()==ID_name)
1434 if(identifier==
"__sync_fetch_and_add" ||
1435 identifier==
"__sync_fetch_and_sub" ||
1436 identifier==
"__sync_fetch_and_or" ||
1437 identifier==
"__sync_fetch_and_and" ||
1438 identifier==
"__sync_fetch_and_xor" ||
1439 identifier==
"__sync_fetch_and_nand" ||
1440 identifier==
"__sync_add_and_fetch" ||
1441 identifier==
"__sync_sub_and_fetch" ||
1442 identifier==
"__sync_or_and_fetch" ||
1443 identifier==
"__sync_and_and_fetch" ||
1444 identifier==
"__sync_xor_and_fetch" ||
1445 identifier==
"__sync_nand_and_fetch" ||
1446 identifier==
"__sync_val_compare_and_swap" ||
1447 identifier==
"__sync_lock_test_and_set" ||
1448 identifier==
"__sync_lock_release")
1457 error() <<
"__sync_* primitives take as least one argument" 1464 if(ptr_arg.
type().
id()!=ID_pointer)
1467 error() <<
"__sync_* primitives take a pointer as first argument" 1473 result.add_source_location()=source_location;
1474 result.set_identifier(identifier);
1482 else if(identifier==
"__atomic_load_n")
1491 error() << identifier <<
" expects two arguments" <<
eom;
1497 if(ptr_arg.
type().
id()!=ID_pointer)
1500 error() << identifier <<
" takes a pointer as first argument" 1506 result.add_source_location()=source_location;
1507 result.set_identifier(identifier);
1516 else if(identifier==
"__atomic_store_n")
1525 error() << identifier <<
" expects three arguments" <<
eom;
1531 if(ptr_arg.
type().
id()!=ID_pointer)
1534 error() << identifier <<
" takes a pointer as first argument" 1540 result.add_source_location()=source_location;
1541 result.set_identifier(identifier);
1551 else if(identifier==
"__atomic_exchange_n")
1560 error() << identifier <<
" expects three arguments" <<
eom;
1566 if(ptr_arg.
type().
id()!=ID_pointer)
1569 error() << identifier <<
" takes a pointer as first argument" 1575 result.add_source_location()=source_location;
1576 result.set_identifier(identifier);
1586 else if(identifier==
"__atomic_load" ||
1587 identifier==
"__atomic_store")
1595 error() << identifier <<
" expects three arguments" <<
eom;
1599 if(fargs.
operands[0].type().id()!=ID_pointer)
1602 error() << identifier <<
" takes a pointer as first argument" 1607 if(fargs.
operands[1].type().id()!=ID_pointer)
1610 error() << identifier <<
" takes a pointer as second argument" 1618 result.add_source_location()=source_location;
1619 result.set_identifier(identifier);
1629 else if(identifier==
"__atomic_exchange")
1636 error() << identifier <<
" expects four arguments" <<
eom;
1640 if(fargs.
operands[0].type().id()!=ID_pointer)
1643 error() << identifier <<
" takes a pointer as first argument" 1648 if(fargs.
operands[1].type().id()!=ID_pointer)
1651 error() << identifier <<
" takes a pointer as second argument" 1656 if(fargs.
operands[2].type().id()!=ID_pointer)
1659 error() << identifier <<
" takes a pointer as third argument" 1667 result.add_source_location()=source_location;
1668 result.set_identifier(identifier);
1679 else if(identifier==
"__atomic_compare_exchange_n" ||
1680 identifier==
"__atomic_compare_exchange")
1690 error() << identifier <<
" expects six arguments" <<
eom;
1694 if(fargs.
operands[0].type().id()!=ID_pointer)
1697 error() << identifier <<
" takes a pointer as first argument" 1702 if(fargs.
operands[1].type().id()!=ID_pointer)
1705 error() << identifier <<
" takes a pointer as second argument" 1710 if(identifier==
"__atomic_compare_exchange" &&
1711 fargs.
operands[2].type().id()!=ID_pointer)
1714 error() << identifier <<
" takes a pointer as third argument" 1722 result.add_source_location()=source_location;
1723 result.set_identifier(identifier);
1728 if(identifier==
"__atomic_compare_exchange")
1741 else if(identifier==
"__atomic_add_fetch" ||
1742 identifier==
"__atomic_sub_fetch" ||
1743 identifier==
"__atomic_and_fetch" ||
1744 identifier==
"__atomic_xor_fetch" ||
1745 identifier==
"__atomic_or_fetch" ||
1746 identifier==
"__atomic_nand_fetch")
1751 error() <<
"__atomic_*_fetch primitives take three arguments" 1758 if(ptr_arg.
type().
id()!=ID_pointer)
1761 error() <<
"__atomic_*_fetch primitives take pointer as first argument" 1767 result.add_source_location()=source_location;
1768 result.set_identifier(identifier);
1776 else if(identifier==
"__atomic_fetch_add" ||
1777 identifier==
"__atomic_fetch_sub" ||
1778 identifier==
"__atomic_fetch_and" ||
1779 identifier==
"__atomic_fetch_xor" ||
1780 identifier==
"__atomic_fetch_or" ||
1781 identifier==
"__atomic_fetch_nand")
1786 error() <<
"__atomic_fetch_* primitives take three arguments" 1793 if(ptr_arg.
type().
id()!=ID_pointer)
1796 error() <<
"__atomic_fetch_* primitives take pointer as first argument" 1802 result.add_source_location()=source_location;
1803 result.set_identifier(identifier);
1811 else if(identifier==
"__atomic_test_and_set")
1814 else if(identifier==
"__atomic_clear")
1817 else if(identifier==
"__atomic_thread_fence")
1820 else if(identifier==
"__atomic_signal_fence")
1823 else if(identifier==
"__atomic_always_lock_free")
1826 else if(identifier==
"__atomic_is_lock_free")
1831 for(std::size_t i=0; i<expr.
get_sub().size(); i++)
1833 if(expr.
get_sub()[i].id()==ID_cpp_name)
1840 typet name(ID_name);
1841 name.
set(ID_identifier, tmp);
1848 if(expr.
get_sub().size()>=1 &&
1849 expr.
get_sub().front().id()==ID_name)
1853 if(
id==ID_const_cast ||
1854 id==ID_dynamic_cast ||
1855 id==ID_reinterpret_cast ||
1858 expr.
id(
"cast_expression");
1870 assert(symbol_expr.
id()!=ID_type);
1872 if(symbol_expr.
id()==ID_member)
1874 if(symbol_expr.
operands().empty() ||
1877 if(symbol_expr.
type().
get(ID_return_type)!=ID_constructor)
1881 if(symbol_expr.
type().
id()!=ID_code)
1884 error() <<
"object missing" <<
eom;
1893 exprt ptrmem(ID_ptrmember);
1897 ptrmem.
add(ID_component_cpp_name)=expr;
1901 symbol_expr.
swap(ptrmem);
1910 if(expr.
id()==ID_symbol)
1922 tmp.
set(ID_C_implicit,
true);
1924 tmp.
set(ID_C_lvalue,
true);
1935 bool is_qualified=
false;
1940 if(expr.
function().
get(ID_component_cpp_name)==ID_cpp_name)
1974 tmp_object_expr.
set(ID_C_lvalue,
true);
1975 tmp_object_expr.set(ID_mode, ID_cpp);
1976 expr.
swap(tmp_object_expr);
1980 exprt typecast(
"explicit-typecast");
1981 typecast.
type()=pod;
1985 expr.
swap(typecast);
1990 error() <<
"zero or one argument expected" <<
eom;
1996 else if(expr.
function().
id()==
"cast_expression")
2004 else if(expr.
function().
id()==
"cpp_dummy_destructor")
2007 expr.
set(ID_statement, ID_skip);
2020 const exprt &bound =
2026 error() <<
"pointer-to-member not bound" <<
eom;
2031 assert(bound.
type().
id()==ID_pointer);
2057 error() <<
"expecting code as argument" <<
eom;
2066 if(op0.
id()==ID_member || op0.
id()==ID_ptrmember)
2068 vtptr_member.
id(op0.
id());
2073 vtptr_member.
id(ID_ptrmember);
2074 exprt this_expr(
"cpp-this");
2092 vtptr_member.
set(ID_component_name, vtable_name);
2099 exprt vtentry_member(ID_ptrmember);
2101 vtentry_member.
set(ID_component_name, vtentry_component_name);
2104 assert(vtentry_member.
type().
id()==ID_pointer);
2109 vtentry_member.
swap(tmp);
2130 irept name(ID_name);
2131 name.
set(ID_identifier,
"operator()");
2135 cppname.
get_sub().push_back(name);
2137 exprt member(ID_member);
2138 member.
add(ID_component_cpp_name)=cppname;
2150 error() <<
"function call expects function or function " 2151 <<
"pointer as argument, but got `" 2159 if(expr.
type().
id()==ID_constructor)
2166 assert(parameters.size()>=1);
2168 const typet &this_type=parameters[0].type();
2176 tmp_object_expr.
set(ID_C_lvalue,
true);
2177 tmp_object_expr.set(ID_mode, ID_cpp);
2181 exprt new_object(
"new_object", tmp_object_expr.type());
2182 new_object.
set(ID_C_lvalue,
true);
2184 assert(
follow(tmp_object_expr.type()).
id()==ID_struct);
2192 if(member.
get_bool(ID_C_not_accessible))
2194 assert(member.
get(ID_C_access)!=
"");
2195 tmp_object_expr.set(ID_C_not_accessible,
true);
2196 tmp_object_expr.set(ID_C_access, member.
get(ID_C_access));
2206 for(struct_typet::componentst::const_iterator
2207 it=components.begin();
2208 it!=components.end();
2211 const typet &type=it->type();
2213 if(!it->get_bool(ID_from_base) &&
2214 type.
id()==ID_code &&
2215 type.
find(ID_return_type).
id()==ID_destructor)
2229 tmp_object_expr.add(ID_initializer)=new_code;
2230 expr.
swap(tmp_object_expr);
2247 if(arguments.size()>=1 &&
2248 arguments.front().get(ID_C_base_name)==ID_this &&
2251 const exprt &argument=
2252 static_cast<const exprt &
>(arguments.front());
2255 assert(argument.
type().
id()==ID_pointer);
2257 if(operand.
type().
id()!=ID_pointer &&
2292 if(parameters.size()>expr.
arguments().size())
2296 for(; i<parameters.size(); i++)
2298 if(!parameters[i].has_default_value())
2301 const exprt &value=parameters[i].default_value();
2306 exprt::operandst::iterator arg_it=expr.
arguments().begin();
2307 for(
const auto ¶meter : parameters)
2309 if(parameter.get_bool(ID_C_call_by_value))
2313 if(arg_it->id()!=ID_temporary_object)
2317 exprt arg(
"already_typechecked");
2322 arg_it->source_location(),
2323 parameter.type().subtype(),
2326 arg_it->swap(temporary);
2341 if(statement==ID_cpp_new ||
2342 statement==ID_cpp_new_array)
2346 else if(statement==ID_cpp_delete ||
2347 statement==ID_cpp_delete_array)
2351 else if(statement==ID_preincrement ||
2352 statement==ID_predecrement ||
2353 statement==ID_postincrement ||
2354 statement==ID_postdecrement)
2358 else if(statement==ID_throw)
2362 else if(statement==ID_temporary_object)
2383 const symbolt &symbol=
lookup(member_expr.get(ID_component_name));
2392 const irept &template_type = tag_symbol.
type.
find(ID_C_template);
2393 const irept &template_args = tag_symbol.
type.
find(ID_C_template_arguments);
2395 static_cast<const template_typet &>(template_type),
2396 static_cast<const cpp_template_args_tct &>(template_args));
2399 std::cout <<
"MAP for " << symbol <<
":" << std::endl;
2417 assert(this_type.
id()==ID_pointer);
2418 this_type.
set(ID_C_reference,
true);
2419 this_type.
set(ID_C_this,
true);
2430 expr.
arguments().front().type().remove(ID_C_reference);
2443 if(symbol.
value.
id()==
"cpp_not_typechecked" &&
2455 error() <<
"assignment side effect expected to have two operands" 2469 if(
follow(type0).
id()==ID_struct)
2470 expr.
op0().
set(ID_C_lvalue,
true);
2476 expr.
set(ID_C_lvalue,
true);
2483 std::string strop=
"operator";
2487 if(statement==ID_assign)
2489 else if(statement==ID_assign_shl)
2491 else if(statement==ID_assign_shr)
2493 else if(statement==ID_assign_plus)
2495 else if(statement==ID_assign_minus)
2497 else if(statement==ID_assign_mult)
2499 else if(statement==ID_assign_div)
2501 else if(statement==ID_assign_bitand)
2503 else if(statement==ID_assign_bitor)
2505 else if(statement==ID_assign_bitxor)
2510 error() <<
"bad assignment operator `" << statement <<
"'" <<
eom;
2516 cpp_name.
get_sub().front().set(ID_identifier, strop);
2523 exprt member(ID_member);
2524 member.
set(ID_component_cpp_name, cpp_name);
2544 <<
" expected to have one operand" <<
eom;
2553 tmp_type.id()==ID_pointer)
2562 std::string str_op=
"operator";
2565 if(expr.
get(ID_statement)==ID_preincrement)
2567 else if(expr.
get(ID_statement)==ID_predecrement)
2569 else if(expr.
get(ID_statement)==ID_postincrement)
2574 else if(expr.
get(ID_statement)==ID_postdecrement)
2582 error() <<
"bad assignment operator `" 2590 cpp_name.
get_sub().front().set(ID_identifier, str_op);
2596 exprt member(ID_member);
2597 member.
set(ID_component_cpp_name, cpp_name);
2610 expr.
swap(new_expr);
2618 error() <<
"unary operator * expects one operand" <<
eom;
2625 if(op_type.
id()==ID_pointer &&
2629 error() <<
"pointer-to-member must use " 2630 <<
"the .* or ->* operators" <<
eom;
2639 assert(expr.
id()==
"pointer-to-member");
2640 assert(expr.
operands().size() == 2);
2646 error() <<
"pointer-to-member expected" <<
eom;
2658 if(t0.id()!=ID_struct)
2661 error() <<
"pointer-to-member type error" <<
eom;
2671 error() <<
"pointer-to-member type error" <<
eom;
2679 if(expr.
op0().
id()==ID_dereference)
2699 if(expr.
id()==ID_symbol)
2702 symbol_tablet::symbolst::const_iterator it=
2707 if(it->second.value.id()==
"cpp_not_typechecked")
2716 bool override_constantness = expr.
get_bool(ID_C_override_constantness);
2723 if(expr.
id()==ID_cpp_name)
2731 if(override_constantness)
2732 expr.
type().
set(ID_C_constant,
false);
2745 if(expr.
id()!=
"explicit-typecast")
2752 if(expr.
type().
id()==ID_cpp_name &&
2754 (op0_id==ID_unary_plus ||
2755 op0_id==ID_unary_minus ||
2756 op0_id==ID_address_of ||
2757 op0_id==ID_dereference))
2759 exprt resolve_result=
2765 if(resolve_result.
id()!=ID_type)
2769 exprt new_binary_expr;
2771 new_binary_expr.
operands().resize(2);
2775 if(op0_id==ID_unary_plus)
2776 new_binary_expr.
id(ID_plus);
2777 else if(op0_id==ID_unary_minus)
2778 new_binary_expr.
id(ID_minus);
2779 else if(op0_id==ID_address_of)
2780 new_binary_expr.
id(ID_bitand);
2781 else if(op0_id==ID_dereference)
2782 new_binary_expr.
id(ID_mult);
2785 expr.
swap(new_binary_expr);
2795 error() <<
"operator `" << expr.
id() <<
"' expects two operands" 2816 error() <<
"comma operator expects two operands" <<
eom;
side_effect_expr_function_callt & to_side_effect_expr_function_call(exprt &expr)
void typecheck_function_expr(exprt &expr, const cpp_typecheck_fargst &fargs)
The type of an expression.
irep_idt name
The unique identifier.
exprt size_of_expr(const typet &type, const namespacet &ns)
void typecheck_expr_dereference(exprt &expr)
struct configt::ansi_ct ansi_c
virtual void typecheck_side_effect_assignment(side_effect_exprt &expr)
void typecheck_side_effect_function_call(side_effect_expr_function_callt &expr)
void typecheck_type(typet &type)
A generic base class for relations, i.e., binary predicates.
pointer_typet pointer_type(const typet &subtype)
void new_temporary(const source_locationt &source_location, const typet &, const exprt::operandst &ops, exprt &temporary)
void typecheck_expr_member(exprt &expr)
virtual void typecheck_expr_index(exprt &expr)
void typecheck_expr_rel(binary_relation_exprt &expr)
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
std::vector< irept > subt
void add_implicit_dereference(exprt &expr)
static exprt collect_comma_expression(const exprt &src)
bool base_type_eq(const typet &type1, const typet &type2, const namespacet &ns)
bool static_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
bool has_base(const irep_idt &id) const
bool find_parent(const symbolt &symb, const irep_idt &base_name, irep_idt &identifier)
const code_typet & to_code_type(const typet &type)
Cast a generic typet to a code_typet.
exprt::operandst operands
void copy_to_operands(const exprt &expr)
irept cpp_exception_list(const typet &src, const namespacet &ns)
turns a type into a list of relevant exception IDs
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
cpp_namet & to_cpp_name(irept &cpp_name)
std::vector< componentt > componentst
void move_to_operands(exprt &expr)
std::vector< parametert > parameterst
void typecheck_expr_function_identifier(exprt &expr)
void already_typechecked(irept &irep)
bool overloadable(const exprt &expr)
virtual void typecheck_code(codet &code)
exprt value
Initial value of symbol.
const componentst & components() const
template_mapt template_map
The trinary if-then-else operator.
void explicit_typecast_ambiguity(exprt &expr)
const class_typet & to_class_type(const typet &type)
Cast a generic typet to a class_typet.
void typecheck_method_application(side_effect_expr_function_callt &expr)
void typecheck_expr_delete(exprt &expr)
void typecheck_expr_this(exprt &expr)
virtual void implicit_typecast(exprt &expr, const typet &type)
Symbol table entry.This is a symbol in the symbol table, stored in an object of type symbol_tablet...
void build(const template_typet &template_type, const cpp_template_args_tct &template_args)
static mstreamt & eom(mstreamt &m)
bool standard_conversion_function_to_pointer(const exprt &expr, exprt &new_expr) const
Function-to-pointer conversion.
bool get_bool(const irep_namet &name) const
void typecheck_expr_typecast(exprt &expr)
bool is_qualified() const
void typecheck_expr_binary_arithmetic(exprt &expr)
codet cpp_destructor(const source_locationt &source_location, const exprt &object)
virtual void typecheck_expr(exprt &expr)
symbol_tablet & symbol_table
void typecheck_expr_explicit_typecast(exprt &expr)
bool dynamic_typecast(const exprt &expr, const typet &type, exprt &new_expr)
Expression Initialization.
void add_method_body(symbolt *_method_symbol)
const irep_idt & id() const
const source_locationt & source_location() const
void typecheck_expr_ptrmember(exprt &expr)
void typecheck_function_call_arguments(side_effect_expr_function_callt &expr)
void elaborate_class_template(const typet &type)
elaborate class template instances
virtual void typecheck_expr_side_effect(side_effect_exprt &expr)
void typecheck_expr_explicit_constructor_call(exprt &expr)
The boolean constant true.
virtual void typecheck_expr_operands(exprt &expr)
A reference into the symbol table.
void typecheck_cast_expr(exprt &expr)
reference_typet reference_type(const typet &subtype)
struct operator_entryt operators[]
const source_locationt & find_source_location() const
source_locationt source_location
bool cpp_is_pod(const typet &type) const
Operator to dereference a pointer.
bool reinterpret_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
virtual void typecheck_expr_binary_arithmetic(exprt &expr)
C++ Language Type Checking.
bool is_reference(const typet &type)
TO_BE_DOCUMENTED.
const irep_idt & get(const irep_namet &name) const
virtual void read(const typet &src) override
std::string cpp_type2name(const typet &type)
virtual void typecheck_expr(exprt &expr)
Base class for tree-like data structures with sharing.
#define forall_operands(it, expr)
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast a generic exprt to a symbol_exprt.
irep_idt class_identifier
void add_object(const exprt &expr)
C++ Language Type Checking.
const typet & follow(const typet &) const
void typecheck_expr_throw(exprt &expr)
bitvector_typet index_type()
const struct_typet & to_struct_type(const typet &type)
Cast a generic typet to a struct_typet.
dstringt has one field, an unsigned integer no which is an index into a static table of strings...
void typecheck_side_effect_assignment(side_effect_exprt &expr)
void convert_pmop(exprt &expr)
Operator to return the address of an object.
void zero_initializer(const exprt &object, const typet &type, const source_locationt &source_location, exprt::operandst &ops)
exprt resolve(const cpp_namet &cpp_name, const cpp_typecheck_resolvet::wantt want, const cpp_typecheck_fargst &fargs, bool fail_with_exception=true)
The boolean constant false.
virtual void typecheck_expr_function_identifier(exprt &expr)
void typecheck_expr_trinary(if_exprt &expr)
virtual void typecheck_function_call_arguments(side_effect_expr_function_callt &expr)
cpp_scopet & set_scope(const irep_idt &identifier)
A function call side effect.
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
bool get_component(const source_locationt &source_location, const exprt &object, const irep_idt &component_name, exprt &member)
void typecheck_expr_address_of(exprt &expr)
virtual exprt do_special_functions(side_effect_expr_function_callt &expr)
typet type
Type of symbol.
virtual void typecheck_expr_sizeof(exprt &expr)
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
message_handlert & get_message_handler()
bool operator_is_overloaded(exprt &expr)
bool standard_conversion_lvalue_to_rvalue(const exprt &expr, exprt &new_expr) const
Lvalue-to-rvalue conversion.
Base type of C structs and unions, and C++ classes.
mstreamt & result() const
bool is_number(const typet &type)
virtual bool is_subset_of(const qualifierst &other) const override
void typecheck_expr_comma(exprt &expr)
std::string type2cpp(const typet &type, const namespacet &ns)
const array_typet & to_array_type(const typet &type)
Cast a generic typet to an array_typet.
Base class for all expressions.
const parameterst & parameters() const
cpp_scopet & current_scope()
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a generic typet to a struct_union_typet.
source_locationt & add_source_location()
const source_locationt & source_location() const
virtual void typecheck_expr_dereference(exprt &expr)
irept & add(const irep_namet &name)
virtual std::string to_string(const typet &type)
const std::string & get_string(const irep_namet &name) const
exprt::operandst & arguments()
void typecheck_expr_side_effect(side_effect_exprt &expr)
source_locationt & add_source_location()
void typecheck_expr_main(exprt &expr)
Called after the operands are done.
bool standard_conversion_array_to_pointer(const exprt &expr, exprt &new_expr) const
Array-to-pointer conversion.
Expression to hold a symbol (variable)
virtual void typecheck_expr_rel(binary_relation_exprt &expr)
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
A statement in a programming language.
signedbv_typet signed_int_type()
void typecheck_expr_cpp_name(exprt &expr, const cpp_typecheck_fargst &fargs)
exprt cpp_symbol_expr(const symbolt &symbol)
void remove(const irep_namet &name)
void typecheck_side_effect_inc_dec(side_effect_exprt &expr)
const typet & subtype() const
virtual void typecheck_expr_address_of(exprt &expr)
virtual void typecheck_expr_comma(exprt &expr)
An expression containing a side effect.
void typecheck_expr_sizeof(exprt &expr)
bool implicit_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
implicit conversion sequence
virtual void typecheck_expr_main(exprt &expr)
void typecheck_expr_index(exprt &expr)
const irept & find(const irep_namet &name) const
codet cpp_constructor(const source_locationt &source_location, const exprt &object, const exprt::operandst &operands)
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See namespace_baset::lookup().
void typecheck_expr_new(exprt &expr)
void set(const irep_namet &name, const irep_idt &value)
const componentt & get_component(const irep_idt &component_name) const
const irep_idt & get_statement() const
void print(std::ostream &out) const
#define forall_irep(it, irep)