Go to the documentation of this file.
38 const irep_idt &
id = b.type().get_identifier();
39 if(
lookup(
id).base_name == base_name)
52 if(expr.
id()==ID_cpp_name)
54 else if(expr.
id()==
"cpp-this")
56 else if(expr.
id()==
"pointer-to-member")
58 else if(expr.
id() == ID_new_object)
64 else if(expr.
id()==
"explicit-typecast")
66 else if(expr.
id()==
"explicit-constructor-call")
71 std::cerr <<
"E: " << expr.
pretty() <<
'\n';
72 std::cerr <<
"cpp_typecheckt::typecheck_expr_main got nil\n";
76 else if(expr.
id()==ID_code)
79 std::cerr <<
"E: " << expr.
pretty() <<
'\n';
80 std::cerr <<
"cpp_typecheckt::typecheck_expr_main got code\n";
84 else if(expr.
id()==ID_symbol)
88 std::cerr <<
"E: " << expr.
pretty() <<
'\n';
89 std::cerr <<
"cpp_typecheckt::typecheck_expr_main got symbol\n";
92 else if(expr.
id()==
"__is_base_of")
106 if(base.
id()!=ID_struct || deriv.
id()!=ID_struct)
119 else if(expr.
id()==ID_msc_uuidof)
125 expr.
set(ID_C_lvalue,
true);
127 else if(expr.
id()==ID_noexcept)
132 else if(expr.
id()==ID_initializer_list)
134 expr.
type().
id(ID_initializer_list);
155 error() <<
"error: lvalue to rvalue conversion" <<
eom;
166 error() <<
"error: array to pointer conversion" <<
eom;
177 error() <<
"error: function to pointer conversion" <<
eom;
188 error() <<
"error: lvalue to rvalue conversion" <<
eom;
199 error() <<
"error: array to pointer conversion" <<
eom;
210 error() <<
"error: function to pointer conversion" <<
eom;
215 if(expr.
op1().
get(ID_statement)==ID_throw &&
216 expr.
op2().
get(ID_statement)!=ID_throw)
218 else if(expr.
op2().
get(ID_statement)==ID_throw &&
219 expr.
op1().
get(ID_statement)!=ID_throw)
221 else if(expr.
op1().
type().
id()==ID_empty &&
227 error() <<
"error: bad types for operands" <<
eom;
259 else if(expr.
op1().
type().
id()==ID_array &&
286 error() <<
"error: types are incompatible.\n"
296 expr.
set(ID_C_lvalue,
true);
316 static_cast<const typet &
>(expr.
find(ID_type_arg));
318 if(type.
id()==ID_cpp_name)
330 if(symbol_expr.
id()!=ID_type)
336 else if(type.
id()==ID_array)
349 if(symbol_expr.
id()!=ID_type)
372 if(expr.
id()==ID_cpp_name)
374 else if(expr.
id()==ID_member)
379 else if(expr.
id()==ID_ptrmember)
387 std::string op_name=
"operator->";
403 exprt tmp(ID_already_typechecked);
405 function_call.
swap(tmp);
407 expr.
op0().
swap(function_call);
429 if(t.
id()==ID_struct ||
430 t.
id() == ID_incomplete_struct ||
432 t.
id()==ID_c_enum || t.
id() == ID_c_enum_tag)
454 { ID_unary_minus,
"-" },
466 { ID_notequal,
"!=" },
467 { ID_dereference,
"*" },
468 { ID_ptrmember,
"->" },
479 else if(expr.
id()==ID_dereference &&
485 if(expr.
id()==
"explicit-typecast")
491 std::string op_name=std::string(
"operator")+
"("+
cpp_type2name(t)+
")";
501 bool found_in_struct=
false;
505 if(t0.
id()==ID_struct)
509 if(!c.get_bool(ID_from_base) && c.get_base_name() == op_name)
511 found_in_struct=
true;
521 exprt member(ID_member);
522 member.
add(ID_component_cpp_name)= cpp_name;
524 exprt tmp(ID_already_typechecked);
533 for(exprt::operandst::const_iterator
535 it!=(expr).operands().end();
537 function_call.
arguments().push_back(*it);
542 if(expr.
id()==ID_ptrmember)
545 exprt tmp(ID_already_typechecked);
552 expr.
swap(function_call);
561 if(expr.
id()==ID_dereference)
562 assert(!expr.
get_bool(ID_C_implicit));
564 std::string op_name=std::string(
"operator")+e->op_name;
587 expr.
op0().
type().
id() == ID_symbol_type &&
611 exprt member(ID_member);
612 member.
add(ID_component_cpp_name)=cpp_name;
614 exprt tmp(ID_already_typechecked);
624 for(exprt::operandst::const_iterator
628 function_call.
arguments().push_back(*it);
653 static_cast<const exprt &
>(
654 static_cast<const irept &
>(cpp_name));
658 function_call.
arguments().push_back(*it);
662 if(expr.
id()==ID_ptrmember)
665 exprt tmp(ID_already_typechecked);
687 error() <<
"address_of expects one operand" <<
eom;
696 error() <<
"expr not an lvalue" <<
eom;
703 assert(expr.
op0().
id()==ID_member);
706 address.
set(ID_C_implicit,
true);
710 if(expr.
op0().
id()==ID_address_of &&
717 if(args.size() > 0 && args[0].get(ID_C_base_name)==ID_this)
723 if(code_type.
get_bool(ID_C_is_virtual))
726 error() <<
"error: pointers to virtual methods"
727 <<
" are currently not implemented" <<
eom;
733 expr.
op0().
id() == ID_ptrmember && expr.
op0().
op0().
id() ==
"cpp-this")
760 if(
follow(exception_type).
id()==ID_empty)
763 error() <<
"cannot throw void" <<
eom;
768 expr.
set(ID_exception_list,
777 if(expr.
type().
id()==ID_array)
786 bool size_is_unsigned=(size.
type().
id()==ID_unsignedbv);
787 typet integer_type(size_is_unsigned?ID_unsignedbv:ID_signedbv);
791 expr.
set(ID_statement, ID_cpp_new_array);
806 expr.
set(ID_statement, ID_cpp_new);
813 object_expr.
set(ID_C_lvalue,
true);
816 exprt tmp(ID_already_typechecked);
818 object_expr.
swap(tmp);
822 exprt &initializer=
static_cast<exprt &
>(expr.
add(ID_initializer));
825 if(!initializer.
operands().empty() &&
826 expr.
get(ID_statement)==ID_cpp_new_array)
829 error() <<
"new with array type must not use initializer" <<
eom;
837 expr.
add(ID_initializer).
swap(code.value());
844 exprt &sizeof_expr=
static_cast<exprt &
>(expr.
add(ID_sizeof));
853 if(src.
id()==ID_comma)
875 if(!new_expr.has_value())
894 if(expr.
type().
id()==ID_cpp_name)
905 if(symbol_expr.
id()==ID_type)
929 if(expr.
op0().
id()==ID_initializer_list)
938 exprt tmp(ID_compound_literal, expr.
type());
941 expr.
set(ID_C_lvalue,
true);
957 error() <<
"invalid explicit cast:\n"
968 error() <<
"explicit typecast expects 0 or 1 operands" <<
eom;
979 expr.
id(
"explicit-typecast");
984 assert(expr.
type().
id()==ID_struct);
999 error() <<
"`this' is not allowed here" <<
eom;
1007 assert(this_expr.
type().
id()==ID_pointer);
1018 error() <<
"delete expects one operand" <<
eom;
1024 if(statement==ID_cpp_delete)
1027 else if(statement==ID_cpp_delete_array)
1038 error() <<
"delete takes a pointer type operand, but got `"
1054 new_object.
set(ID_C_lvalue,
true);
1060 if(destructor_code.has_value())
1064 expr.
set(ID_destructor, destructor_code.value());
1074 std::cout <<
"E: " << expr.pretty() <<
'\n';
1086 error() <<
"error: member operator expects one operand" <<
eom;
1102 exprt tmp(ID_cpp_dummy_destructor);
1113 if(followed_op0_type.
id()==ID_incomplete_struct ||
1114 followed_op0_type.
id()==ID_incomplete_union)
1117 error() <<
"error: member operator got incomplete type "
1118 <<
"on left hand side" <<
eom;
1122 if(followed_op0_type.
id()!=ID_struct &&
1123 followed_op0_type.
id()!=ID_union)
1126 error() <<
"error: member operator requires struct/union type "
1127 <<
"on left hand side but got `"
1155 if(symbol_expr.
id()==ID_dereference)
1157 assert(symbol_expr.
get_bool(ID_C_implicit));
1159 symbol_expr.
swap(tmp);
1162 assert(symbol_expr.
id()==ID_symbol ||
1163 symbol_expr.
id()==ID_member ||
1164 symbol_expr.
id()==ID_constant);
1170 if(symbol_expr.
id()==ID_symbol)
1173 symbol_expr.
type().
id() == ID_code &&
1177 error() <<
"error: member `"
1178 <<
lookup(symbol_expr.
get(ID_identifier)).base_name
1179 <<
"' is a constructor" <<
eom;
1191 error() <<
"error: `"
1192 << symbol_expr.
get(ID_identifier)
1193 <<
"' is not static member "
1194 <<
"of class `" <<
to_string(type) <<
"'"
1203 else if(symbol_expr.
id()==ID_constant)
1209 const irep_idt component_name=symbol_expr.
get(ID_component_name);
1211 expr.
remove(ID_component_cpp_name);
1212 expr.
set(ID_component_name, component_name);
1215 const irep_idt &component_name=expr.
get(ID_component_name);
1217 assert(component_name!=
"");
1238 error() <<
"error: member `" << component_name
1240 <<
"' not found" <<
eom;
1246 if(expr.
type().
id()==ID_code)
1249 symbol_tablet::symbolst::const_iterator it=
1254 if(it->second.value.id() == ID_cpp_not_typechecked)
1264 assert(expr.
id()==ID_ptrmember);
1269 error() <<
"error: ptrmember operator expects one operand" <<
eom;
1278 error() <<
"error: ptrmember operator requires pointer type "
1279 <<
"on left hand side, but got `"
1289 op.
id(ID_dereference);
1306 error() <<
"cast expressions expect one operand" <<
eom;
1316 f_op.
get_sub().front().get(ID_identifier);
1318 if(f_op.
get_sub().size()!=2 ||
1319 f_op.
get_sub()[1].id()!=ID_template_args)
1322 error() <<
id <<
" expects template argument" <<
eom;
1326 irept &template_arguments=f_op.
get_sub()[1].add(ID_arguments);
1328 if(template_arguments.
get_sub().size()!=1)
1331 error() <<
id <<
" expects one template argument" <<
eom;
1335 irept &template_arg=template_arguments.
get_sub().front();
1337 if(template_arg.
id() != ID_type && template_arg.
id() != ID_ambiguous)
1340 error() <<
id <<
" expects a type as template argument" <<
eom;
1345 template_arguments.
get_sub().front().add(ID_type));
1352 if(
id==ID_const_cast)
1357 error() <<
"type mismatch on const_cast:\n"
1364 else if(
id==ID_dynamic_cast)
1369 error() <<
"type mismatch on dynamic_cast:\n"
1376 else if(
id==ID_reinterpret_cast)
1381 error() <<
"type mismatch on reinterpret_cast:\n"
1388 else if(
id==ID_static_cast)
1393 error() <<
"type mismatch on static_cast:\n"
1403 expr.
swap(new_expr);
1413 if(expr.
get_sub().size()==1 &&
1414 expr.
get_sub()[0].id()==ID_name)
1418 if(identifier==
"__sync_fetch_and_add" ||
1419 identifier==
"__sync_fetch_and_sub" ||
1420 identifier==
"__sync_fetch_and_or" ||
1421 identifier==
"__sync_fetch_and_and" ||
1422 identifier==
"__sync_fetch_and_xor" ||
1423 identifier==
"__sync_fetch_and_nand" ||
1424 identifier==
"__sync_add_and_fetch" ||
1425 identifier==
"__sync_sub_and_fetch" ||
1426 identifier==
"__sync_or_and_fetch" ||
1427 identifier==
"__sync_and_and_fetch" ||
1428 identifier==
"__sync_xor_and_fetch" ||
1429 identifier==
"__sync_nand_and_fetch" ||
1430 identifier==
"__sync_val_compare_and_swap" ||
1431 identifier==
"__sync_lock_test_and_set" ||
1432 identifier==
"__sync_lock_release")
1441 error() <<
"__sync_* primitives take as least one argument"
1448 if(ptr_arg.
type().
id()!=ID_pointer)
1451 error() <<
"__sync_* primitives take a pointer as first argument"
1457 result.add_source_location()=source_location;
1458 result.set_identifier(identifier);
1466 else if(identifier==
"__atomic_load_n")
1475 error() << identifier <<
" expects two arguments" <<
eom;
1481 if(ptr_arg.
type().
id()!=ID_pointer)
1484 error() << identifier <<
" takes a pointer as first argument"
1490 result.add_source_location()=source_location;
1491 result.set_identifier(identifier);
1500 else if(identifier==
"__atomic_store_n")
1509 error() << identifier <<
" expects three arguments" <<
eom;
1515 if(ptr_arg.
type().
id()!=ID_pointer)
1518 error() << identifier <<
" takes a pointer as first argument"
1524 result.add_source_location()=source_location;
1525 result.set_identifier(identifier);
1535 else if(identifier==
"__atomic_exchange_n")
1544 error() << identifier <<
" expects three arguments" <<
eom;
1550 if(ptr_arg.
type().
id()!=ID_pointer)
1553 error() << identifier <<
" takes a pointer as first argument"
1559 result.add_source_location()=source_location;
1560 result.set_identifier(identifier);
1570 else if(identifier==
"__atomic_load" ||
1571 identifier==
"__atomic_store")
1579 error() << identifier <<
" expects three arguments" <<
eom;
1583 if(fargs.
operands[0].type().id()!=ID_pointer)
1586 error() << identifier <<
" takes a pointer as first argument"
1591 if(fargs.
operands[1].type().id()!=ID_pointer)
1594 error() << identifier <<
" takes a pointer as second argument"
1602 result.add_source_location()=source_location;
1603 result.set_identifier(identifier);
1613 else if(identifier==
"__atomic_exchange")
1620 error() << identifier <<
" expects four arguments" <<
eom;
1624 if(fargs.
operands[0].type().id()!=ID_pointer)
1627 error() << identifier <<
" takes a pointer as first argument"
1632 if(fargs.
operands[1].type().id()!=ID_pointer)
1635 error() << identifier <<
" takes a pointer as second argument"
1640 if(fargs.
operands[2].type().id()!=ID_pointer)
1643 error() << identifier <<
" takes a pointer as third argument"
1651 result.add_source_location()=source_location;
1652 result.set_identifier(identifier);
1663 else if(identifier==
"__atomic_compare_exchange_n" ||
1664 identifier==
"__atomic_compare_exchange")
1674 error() << identifier <<
" expects six arguments" <<
eom;
1678 if(fargs.
operands[0].type().id()!=ID_pointer)
1681 error() << identifier <<
" takes a pointer as first argument"
1686 if(fargs.
operands[1].type().id()!=ID_pointer)
1689 error() << identifier <<
" takes a pointer as second argument"
1694 if(identifier==
"__atomic_compare_exchange" &&
1695 fargs.
operands[2].type().id()!=ID_pointer)
1698 error() << identifier <<
" takes a pointer as third argument"
1706 result.add_source_location()=source_location;
1707 result.set_identifier(identifier);
1712 if(identifier==
"__atomic_compare_exchange")
1725 else if(identifier==
"__atomic_add_fetch" ||
1726 identifier==
"__atomic_sub_fetch" ||
1727 identifier==
"__atomic_and_fetch" ||
1728 identifier==
"__atomic_xor_fetch" ||
1729 identifier==
"__atomic_or_fetch" ||
1730 identifier==
"__atomic_nand_fetch")
1735 error() <<
"__atomic_*_fetch primitives take three arguments"
1742 if(ptr_arg.
type().
id()!=ID_pointer)
1745 error() <<
"__atomic_*_fetch primitives take pointer as first argument"
1751 result.add_source_location()=source_location;
1752 result.set_identifier(identifier);
1760 else if(identifier==
"__atomic_fetch_add" ||
1761 identifier==
"__atomic_fetch_sub" ||
1762 identifier==
"__atomic_fetch_and" ||
1763 identifier==
"__atomic_fetch_xor" ||
1764 identifier==
"__atomic_fetch_or" ||
1765 identifier==
"__atomic_fetch_nand")
1770 error() <<
"__atomic_fetch_* primitives take three arguments"
1777 if(ptr_arg.
type().
id()!=ID_pointer)
1780 error() <<
"__atomic_fetch_* primitives take pointer as first argument"
1786 result.add_source_location()=source_location;
1787 result.set_identifier(identifier);
1795 else if(identifier==
"__atomic_test_and_set")
1798 else if(identifier==
"__atomic_clear")
1801 else if(identifier==
"__atomic_thread_fence")
1804 else if(identifier==
"__atomic_signal_fence")
1807 else if(identifier==
"__atomic_always_lock_free")
1810 else if(identifier==
"__atomic_is_lock_free")
1815 for(std::size_t i=0; i<expr.
get_sub().size(); i++)
1817 if(expr.
get_sub()[i].id()==ID_cpp_name)
1824 typet name(ID_name);
1825 name.
set(ID_identifier, tmp);
1832 if(expr.
get_sub().size()>=1 &&
1833 expr.
get_sub().front().id()==ID_name)
1837 if(
id==ID_const_cast ||
1838 id==ID_dynamic_cast ||
1839 id==ID_reinterpret_cast ||
1842 expr.
id(ID_cast_expression);
1854 assert(symbol_expr.
id()!=ID_type);
1856 if(symbol_expr.
id()==ID_member)
1858 if(symbol_expr.
operands().empty() ||
1865 if(symbol_expr.
type().
id()!=ID_code)
1868 error() <<
"object missing" <<
eom;
1877 exprt ptrmem(ID_ptrmember);
1881 ptrmem.
add(ID_component_cpp_name)=expr;
1885 symbol_expr.
swap(ptrmem);
1894 if(expr.
id()==ID_symbol)
1906 tmp.
set(ID_C_implicit,
true);
1908 tmp.
set(ID_C_lvalue,
true);
1919 bool is_qualified=
false;
1924 if(expr.
function().
get(ID_component_cpp_name)==ID_cpp_name)
1943 if(expr.
function().
id() == ID_pod_constructor)
1958 tmp_object_expr.
set(ID_C_lvalue,
true);
1959 tmp_object_expr.
set(ID_mode, ID_cpp);
1960 expr.
swap(tmp_object_expr);
1964 exprt typecast(
"explicit-typecast");
1965 typecast.
type()=pod;
1969 expr.
swap(typecast);
1974 error() <<
"zero or one argument expected" <<
eom;
1980 else if(expr.
function().
id() == ID_cast_expression)
1988 else if(expr.
function().
id() == ID_cpp_dummy_destructor)
1991 expr.
set(ID_statement, ID_skip);
2004 const exprt &bound =
2010 error() <<
"pointer-to-member not bound" <<
eom;
2015 assert(bound.
type().
id()==ID_pointer);
2041 error() <<
"expecting code as argument" <<
eom;
2050 if(op0.
id()==ID_member || op0.
id()==ID_ptrmember)
2052 vtptr_member.
id(op0.
id());
2057 vtptr_member.
id(ID_ptrmember);
2058 exprt this_expr(
"cpp-this");
2076 vtptr_member.
set(ID_component_name, vtable_name);
2083 exprt vtentry_member(ID_ptrmember);
2085 vtentry_member.
set(ID_component_name, vtentry_component_name);
2088 assert(vtentry_member.
type().
id()==ID_pointer);
2093 vtentry_member.
swap(tmp);
2116 exprt member(ID_member);
2117 member.
add(ID_component_cpp_name)=cppname;
2129 error() <<
"function call expects function or function "
2130 <<
"pointer as argument, but got `"
2138 if(expr.
type().
id()==ID_constructor)
2145 assert(parameters.size()>=1);
2147 const typet &this_type=parameters[0].type();
2155 tmp_object_expr.
set(ID_C_lvalue,
true);
2156 tmp_object_expr.
set(ID_mode, ID_cpp);
2160 exprt new_object(ID_new_object, tmp_object_expr.
type());
2161 new_object.
set(ID_C_lvalue,
true);
2163 assert(
follow(tmp_object_expr.
type()).
id()==ID_struct);
2171 if(member.
get_bool(ID_C_not_accessible))
2173 assert(member.
get(ID_C_access)!=
"");
2174 tmp_object_expr.
set(ID_C_not_accessible,
true);
2175 tmp_object_expr.
set(ID_C_access, member.
get(ID_C_access));
2185 for(
const auto &c : components)
2187 const typet &type = c.type();
2190 !c.get_bool(ID_from_base) && type.
id() == ID_code &&
2205 tmp_object_expr.
add(ID_initializer)=new_code;
2206 expr.
swap(tmp_object_expr);
2223 if(arguments.size()>=1 &&
2224 arguments.front().get(ID_C_base_name)==ID_this &&
2227 const exprt &argument=
2228 static_cast<const exprt &
>(arguments.front());
2231 assert(argument.
type().
id()==ID_pointer);
2233 if(operand.
type().
id()!=ID_pointer &&
2267 if(parameters.size()>expr.
arguments().size())
2271 for(; i<parameters.size(); i++)
2273 if(!parameters[i].has_default_value())
2276 const exprt &value=parameters[i].default_value();
2281 exprt::operandst::iterator arg_it=expr.
arguments().begin();
2282 for(
const auto ¶meter : parameters)
2284 if(parameter.get_bool(ID_C_call_by_value))
2288 if(arg_it->id()!=ID_temporary_object)
2292 exprt arg(ID_already_typechecked);
2297 arg_it->source_location(),
2298 parameter.type().subtype(),
2301 arg_it->swap(temporary);
2316 if(statement==ID_cpp_new ||
2317 statement==ID_cpp_new_array)
2321 else if(statement==ID_cpp_delete ||
2322 statement==ID_cpp_delete_array)
2326 else if(statement==ID_preincrement ||
2327 statement==ID_predecrement ||
2328 statement==ID_postincrement ||
2329 statement==ID_postdecrement)
2333 else if(statement==ID_throw)
2337 else if(statement==ID_temporary_object)
2367 const irept &template_type = tag_symbol.
type.
find(ID_C_template);
2368 const irept &template_args = tag_symbol.
type.
find(ID_C_template_arguments);
2374 std::cout <<
"MAP for " << symbol <<
":" << std::endl;
2392 assert(this_type.
id()==ID_pointer);
2393 this_type.
set(ID_C_reference,
true);
2394 this_type.
set(ID_C_this,
true);
2405 expr.
arguments().front().type().remove(ID_C_reference);
2419 symbol.
value.
id() == ID_cpp_not_typechecked &&
2431 error() <<
"assignment side effect expected to have two operands"
2445 if(
follow(type0).
id()==ID_struct)
2446 expr.
op0().
set(ID_C_lvalue,
true);
2452 expr.
set(ID_C_lvalue,
true);
2459 std::string strop=
"operator";
2463 if(statement==ID_assign)
2465 else if(statement==ID_assign_shl)
2467 else if(statement==ID_assign_shr)
2469 else if(statement==ID_assign_plus)
2471 else if(statement==ID_assign_minus)
2473 else if(statement==ID_assign_mult)
2475 else if(statement==ID_assign_div)
2477 else if(statement==ID_assign_bitand)
2479 else if(statement==ID_assign_bitor)
2481 else if(statement==ID_assign_bitxor)
2486 error() <<
"bad assignment operator `" << statement <<
"'" <<
eom;
2496 exprt member(ID_member);
2497 member.
set(ID_component_cpp_name, cpp_name);
2517 <<
" expected to have one operand" <<
eom;
2526 tmp_type.
id()==ID_pointer)
2535 std::string str_op=
"operator";
2538 if(expr.
get(ID_statement)==ID_preincrement)
2540 else if(expr.
get(ID_statement)==ID_predecrement)
2542 else if(expr.
get(ID_statement)==ID_postincrement)
2547 else if(expr.
get(ID_statement)==ID_postdecrement)
2555 error() <<
"bad assignment operator `"
2566 exprt member(ID_member);
2567 member.
set(ID_component_cpp_name, cpp_name);
2580 expr.
swap(new_expr);
2588 error() <<
"unary operator * expects one operand" <<
eom;
2595 if(op_type.
id()==ID_pointer &&
2599 error() <<
"pointer-to-member must use "
2600 <<
"the .* or ->* operators" <<
eom;
2609 assert(expr.
id()==
"pointer-to-member");
2610 assert(expr.
operands().size() == 2);
2616 error() <<
"pointer-to-member expected" <<
eom;
2628 if(t0.
id()!=ID_struct)
2631 error() <<
"pointer-to-member type error" <<
eom;
2641 error() <<
"pointer-to-member type error" <<
eom;
2649 if(expr.
op0().
id()==ID_dereference)
2669 if(expr.
id()==ID_symbol)
2672 symbol_tablet::symbolst::const_iterator it=
2677 if(it->second.value.id() == ID_cpp_not_typechecked)
2686 bool override_constantness = expr.
get_bool(ID_C_override_constantness);
2693 if(expr.
id()==ID_cpp_name)
2701 if(override_constantness)
2702 expr.
type().
set(ID_C_constant,
false);
2715 if(expr.
id()!=
"explicit-typecast")
2722 if(expr.
type().
id()==ID_cpp_name &&
2724 (op0_id==ID_unary_plus ||
2725 op0_id==ID_unary_minus ||
2726 op0_id==ID_address_of ||
2727 op0_id==ID_dereference))
2729 exprt resolve_result=
2735 if(resolve_result.
id()!=ID_type)
2739 exprt new_binary_expr;
2741 new_binary_expr.
operands().resize(2);
2745 if(op0_id==ID_unary_plus)
2746 new_binary_expr.
id(ID_plus);
2747 else if(op0_id==ID_unary_minus)
2748 new_binary_expr.
id(ID_minus);
2749 else if(op0_id==ID_address_of)
2750 new_binary_expr.
id(ID_bitand);
2751 else if(op0_id==ID_dereference)
2752 new_binary_expr.
id(ID_mult);
2755 expr.
swap(new_binary_expr);
2765 error() <<
"operator `" << expr.
id() <<
"' expects two operands"
2786 error() <<
"comma operator expects two operands" <<
eom;
virtual void do_initializer(exprt &initializer, const typet &type, bool force_constant)
virtual void read(const typet &src) override
void copy_to_operands(const exprt &expr)
Copy the given argument to the end of exprt's operands.
const componentst & components() const
virtual void typecheck_expr_side_effect(side_effect_exprt &expr)
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
irep_idt class_identifier
void move_to_operands(exprt &expr)
Move the given argument to the end of exprt's operands.
const typet & subtype() const
side_effect_expr_function_callt & to_side_effect_expr_function_call(exprt &expr)
void typecheck_expr_side_effect(side_effect_exprt &) override
void elaborate_class_template(const typet &type)
elaborate class template instances
void typecheck_expr_dereference(exprt &) override
bool is_number(const typet &type)
Returns true if the type is a rational, real, integer, natural, complex, unsignedbv,...
void typecheck_expr_trinary(if_exprt &) override
void convert_pmop(exprt &expr)
const componentt & get_component(const irep_idt &component_name) const
Get the reference to a component with given name.
void typecheck_expr_explicit_constructor_call(exprt &)
const struct_typet & to_struct_type(const typet &type)
Cast a typet to a struct_typet.
void typecheck_expr_cpp_name(exprt &, const cpp_typecheck_fargst &)
void typecheck_expr_typecast(exprt &) override
const struct_union_typet & to_struct_union_type(const typet &type)
Cast a typet to a struct_union_typet.
virtual exprt do_special_functions(side_effect_expr_function_callt &expr)
void already_typechecked(irept &irep)
The type of an expression, extends irept.
std::vector< parametert > parameterst
bool operator_is_overloaded(exprt &)
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
const class_typet & to_class_type(const typet &type)
Cast a typet to a class_typet.
bool reinterpret_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
Base type for structs and unions.
typet type
Type of symbol.
Operator to dereference a pointer.
void typecheck_side_effect_assignment(side_effect_exprt &) override
A side_effect_exprt representation of a function call side effect.
The trinary if-then-else operator.
irept & add(const irep_namet &name)
bool has_base(const irep_idt &id) const
Test whether id is a base class/struct.
exprt::operandst operands
virtual void typecheck_function_call_arguments(side_effect_expr_function_callt &expr)
Typecheck the parameters in a function call expression, and where necessary, make implicit casts arou...
const irept & find(const irep_namet &name) const
void new_temporary(const source_locationt &source_location, const typet &, const exprt::operandst &ops, exprt &temporary)
bool standard_conversion_lvalue_to_rvalue(const exprt &expr, exprt &new_expr) const
Lvalue-to-rvalue conversion.
void typecheck_expr_member(exprt &) override
Base class for all expressions.
bool is_destructor() const
std::vector< componentt > componentst
optionalt< codet > cpp_constructor(const source_locationt &source_location, const exprt &object, const exprt::operandst &operands)
A struct tag type, i.e., struct_typet with an identifier.
virtual void typecheck_expr_address_of(exprt &expr)
auto component(T &struct_expr, const irep_idt &name, const namespacet &ns) -> decltype(struct_expr.op0())
void typecheck_side_effect_inc_dec(side_effect_exprt &)
bool overloadable(const exprt &)
void zero_initializer(const exprt &object, const typet &type, const source_locationt &source_location, exprt::operandst &ops)
virtual void typecheck_expr_binary_arithmetic(exprt &expr)
struct configt::ansi_ct ansi_c
virtual bool is_subset_of(const qualifierst &other) const override
Expression to hold a symbol (variable)
static exprt collect_comma_expression(const exprt &src)
bitvector_typet index_type()
void typecheck_expr_delete(exprt &)
#define UNREACHABLE
This should be used to mark dead code.
bool standard_conversion_array_to_pointer(const exprt &expr, exprt &new_expr) const
Array-to-pointer conversion.
void typecheck_expr_function_identifier(exprt &) override
virtual void typecheck_expr_operands(exprt &expr)
const exprt & size() const
bool cpp_is_pod(const typet &type) const
typet & type()
Return the type of the expression.
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
void typecheck_type(typet &) override
bool get_bool(const irep_namet &name) const
void typecheck_expr_sizeof(exprt &) override
void typecheck_function_expr(exprt &, const cpp_typecheck_fargst &)
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
virtual void typecheck_expr_rel(binary_relation_exprt &expr)
mstreamt & result() const
void typecheck_side_effect_function_call(side_effect_expr_function_callt &) override
signedbv_typet signed_int_type()
void add_method_body(symbolt *_method_symbol)
exprt size_of_expr(const typet &type, const namespacet &ns)
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
irept cpp_exception_list(const typet &src, const namespacet &ns)
turns a type into a list of relevant exception IDs
void add_implicit_dereference(exprt &)
cpp_scopet & current_scope()
source_locationt source_location
virtual void typecheck_expr_function_identifier(exprt &expr)
#define forall_operands(it, expr)
void print(std::ostream &out) const
std::string type2cpp(const typet &type, const namespacet &ns)
virtual void typecheck_expr_dereference(exprt &expr)
bool base_type_eq(const typet &type1, const typet &type2, const namespacet &ns)
Check types for equality across all levels of hierarchy.
const source_locationt & find_source_location() const
Get a source_locationt from the expression or from its operands (non-recursively).
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
void typecheck_expr_explicit_typecast(exprt &)
void typecheck_expr_rel(binary_relation_exprt &) override
void typecheck_function_call_arguments(side_effect_expr_function_callt &) override
const basest & bases() const
Get the collection of base classes/structs.
symbol_tablet & symbol_table
pointer_typet pointer_type(const typet &subtype)
void typecheck_cast_expr(exprt &)
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
bool subtype_typecast(const struct_typet &from, const struct_typet &to) const
const irep_idt & id() const
bool standard_conversion_function_to_pointer(const exprt &expr, exprt &new_expr) const
Function-to-pointer conversion.
void remove(const irep_namet &name)
void add_object(const exprt &expr)
bool get_component(const source_locationt &source_location, const exprt &object, const irep_idt &component_name, exprt &member)
The Boolean constant false.
void typecheck_expr_throw(exprt &)
const parameterst & parameters() const
source_locationt & add_source_location()
virtual void typecheck_side_effect_assignment(side_effect_exprt &expr)
bool static_typecast(const exprt &expr, const typet &type, exprt &new_expr, bool check_constantness=true)
bool is_qualified() const
const irep_idt & get_statement() const
virtual void typecheck_expr(exprt &expr)
void typecheck_expr_main(exprt &) override
Called after the operands are done.
reference_typet reference_type(const typet &subtype)
const std::string & get_string(const irep_namet &name) const
void typecheck_expr(exprt &) override
void typecheck_expr_comma(exprt &) override
exprt value
Initial value of symbol.
Structure type, corresponds to C style structs.
void typecheck_expr_new(exprt &)
const source_locationt & source_location() const
bool const_typecast(const exprt &expr, const typet &type, exprt &new_expr)
virtual void typecheck_expr_main(exprt &expr)
void typecheck_code(codet &) override
std::string cpp_type2name(const typet &type)
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
bool is_reference(const typet &type)
Returns true if the type is a reference.
const irep_idt & get(const irep_namet &name) const
struct operator_entryt operators[]
void set(const irep_namet &name, const irep_idt &value)
const exprt & as_expr() const
exprt::operandst & arguments()
void typecheck_expr_this(exprt &)
A base class for relations, i.e., binary predicates.
void typecheck_expr_index(exprt &) override
void implicit_typecast(exprt &expr, const typet &type) override
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.
void typecheck_expr_binary_arithmetic(exprt &) override
bool find_parent(const symbolt &symb, const irep_idt &base_name, irep_idt &identifier)
const typet & return_type() const
bool implicit_conversion_sequence(const exprt &expr, const typet &type, exprt &new_expr, unsigned &rank)
implicit conversion sequence
bool dynamic_typecast(const exprt &expr, const typet &type, exprt &new_expr)
Base class for tree-like data structures with sharing.
std::string to_string(const typet &) override
void build(const template_typet &template_type, const cpp_template_args_tct &template_args)
Operator to return the address of an object.
source_locationt & add_source_location()
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
void explicit_typecast_ambiguity(exprt &)
optionalt< codet > cpp_destructor(const source_locationt &source_location, const exprt &object)
The Boolean constant true.
exprt resolve(const cpp_namet &cpp_name, const cpp_typecheck_resolvet::wantt want, const cpp_typecheck_fargst &fargs, bool fail_with_exception=true)
template_mapt template_map
void typecheck_method_application(side_effect_expr_function_callt &)
virtual void typecheck_expr_sizeof(exprt &expr)
std::vector< irept > subt
void typecheck_expr_address_of(exprt &) override
const source_locationt & source_location() const
irep_idt name
The unique identifier.
cpp_scopet & set_scope(const irep_idt &identifier)
An expression containing a side effect.
void typecheck_expr_ptrmember(exprt &) override
virtual void typecheck_expr_index(exprt &expr)
cpp_namet & to_cpp_name(irept &cpp_name)
codet representation of an expression statement.
virtual void typecheck_expr_comma(exprt &expr)