41 original_scope(nullptr)
50 for(
const auto &id_ptr : id_set)
52 const cpp_idt &identifier = *id_ptr;
60 identifiers.push_back(e);
71 old_identifiers.swap(identifiers);
73 for(
const auto &old_id : old_identifiers)
83 identifiers.push_back(e);
94 old_identifiers.swap(identifiers);
96 for(
const auto &old_id : old_identifiers)
102 assert(e.
id()!=ID_type);
103 identifiers.push_back(e);
110 if(identifiers.size()==1)
113 exprt e=*identifiers.begin();
114 assert(e.
id()==ID_template_function_instance);
116 const symbolt &template_symbol=
132 identifiers.push_back(
141 old_identifiers.swap(identifiers);
143 for(
const auto &old_id : old_identifiers)
146 identifiers.push_back(old_id);
154 old_identifiers.swap(identifiers);
156 std::set<irep_idt> ids;
157 std::set<exprt> other;
159 for(
const auto &old_id : old_identifiers)
163 if(old_id.id() == ID_symbol)
165 else if(old_id.id() == ID_type && old_id.type().id() == ID_struct_tag)
167 else if(old_id.id() == ID_type && old_id.type().id() == ID_union_tag)
172 if(other.insert(old_id).second)
173 identifiers.push_back(old_id);
177 if(ids.insert(
id).second)
178 identifiers.push_back(old_id);
187 std::cout <<
"RESOLVE MAP:\n";
199 <<
"without instance:\n"
224 const symbolt &compound_symbol=
227 assert(compound_symbol.
type.
id()==ID_struct ||
228 compound_symbol.
type.
id()==ID_union);
258 this_class_identifier <<
'\n';
261 const exprt &this_expr=
273 assert(this_expr.
type().
id()==ID_pointer);
275 object.copy_to_operands(this_expr);
276 object.type().set(ID_C_constant,
278 object.set(ID_C_lvalue,
true);
285 if(object_type.
id()==ID_struct ||
286 object_type.
id()==ID_union)
297 if(
object.is_not_nil())
336 else if(symbol.
type.
id()==ID_c_enum)
340 else if(symbol.
type.
id() == ID_struct)
344 else if(symbol.
type.
id() == ID_union)
360 symbol.
value.
id() == ID_constant)
381 old_identifiers.swap(identifiers);
383 for(
const auto &old_id : old_identifiers)
390 match = (old_id.id() == ID_type);
394 match = (old_id.id() != ID_type);
406 identifiers.push_back(old_id);
418 old_identifiers.swap(identifiers);
423 for(
const auto &old_id : old_identifiers)
428 identifiers.push_back(old_id);
437 old_identifiers.swap(identifiers);
440 std::multimap<std::size_t, exprt> distance_map;
442 for(
const auto &old_id : old_identifiers)
444 unsigned args_distance;
448 std::size_t template_distance=0;
450 if(!old_id.type().get(ID_C_template).empty())
451 template_distance = old_id.type()
452 .find(ID_C_template_arguments)
459 std::size_t total_distance=
461 1000*template_distance+args_distance;
463 distance_map.insert({total_distance, old_id});
467 old_identifiers.clear();
470 if(!distance_map.empty())
472 auto range = distance_map.equal_range(distance_map.begin()->first);
473 for(
auto it = range.first; it != range.second; ++it)
474 old_identifiers.push_back(it->second);
477 if(old_identifiers.size() > 1 && fargs.
in_use)
481 for(resolve_identifierst::const_iterator old_it = old_identifiers.begin();
482 old_it != old_identifiers.end();
486 std::cout <<
"I1: " << old_it->get(ID_identifier) <<
'\n';
489 if(old_it->type().id() != ID_code)
491 identifiers.push_back(*old_it);
497 for(resolve_identifierst::const_iterator resolve_it = old_it + 1;
498 resolve_it != old_identifiers.end();
501 if(resolve_it->type().id() != ID_code)
513 i<f1.
parameters().size() && (f1_better || f2_better);
525 if(type1.
id()==ID_pointer)
531 if(type2.
id()==ID_pointer)
540 if(followed1.
id() != ID_struct || followed2.
id() != ID_struct)
556 if(!f1_better || f2_better)
557 identifiers.push_back(*resolve_it);
563 identifiers.swap(old_identifiers);
574 for(
const auto &identifier : identifiers)
576 if(identifier.id() != ID_type)
579 new_identifiers.push_back(identifier);
594 exprt pod_constructor1(ID_pod_constructor, t1);
595 new_identifiers.push_back(pod_constructor1);
602 exprt pod_constructor2(ID_pod_constructor, t2);
603 new_identifiers.push_back(pod_constructor2);
607 if(symbol_type.
id()==ID_c_enum_tag)
611 exprt pod_constructor3(ID_pod_constructor, t3);
612 new_identifiers.push_back(pod_constructor3);
615 else if(symbol_type.
id()==ID_struct)
628 type.
id() == ID_code &&
629 to_code_type(type).return_type().
id() == ID_constructor)
635 new_identifiers.push_back(e);
641 identifiers.
swap(new_identifiers);
648 if(argument.
id() == ID_ambiguous)
668 if(base_name==ID_unsignedbv ||
669 base_name==ID_signedbv)
671 if(arguments.size()!=1)
675 << base_name <<
" expects one template argument, but got "
680 exprt argument=arguments.front();
682 if(argument.
id()==ID_type)
686 << base_name <<
" expects one integer template argument, "
693 const auto i = numeric_cast<mp_integer>(argument);
706 <<
"template argument must be greater than zero"
714 else if(base_name==ID_fixedbv)
716 if(arguments.size()!=2)
720 << base_name <<
" expects two template arguments, but got "
725 exprt argument0=arguments[0];
727 exprt argument1=arguments[1];
730 if(argument0.
id()==ID_type)
734 << base_name <<
" expects two integer template arguments, "
739 if(argument1.
id()==ID_type)
743 << base_name <<
" expects two integer template arguments, "
748 const auto width = numeric_cast<mp_integer>(argument0);
750 if(!width.has_value())
758 const auto integer_bits = numeric_cast<mp_integer>(argument1);
760 if(!integer_bits.has_value())
772 <<
"template argument must be greater than zero"
777 if(*integer_bits < 0)
781 <<
"template argument must be greater or equal zero"
786 if(*integer_bits > *width)
790 <<
"template argument must be smaller or equal width"
799 else if(base_name==ID_integer)
801 if(!arguments.empty())
805 << base_name <<
" expects no template arguments"
817 else if(base_name==
"dump_scopes")
825 else if(base_name==
"current_scope")
832 else if(base_name == ID_size_t)
836 else if(base_name == ID_ssize_t)
859 assert(!cpp_name.
get_sub().empty());
864 irept::subt::const_iterator
pos=cpp_name.
get_sub().begin();
876 std::string final_base_name;
881 if(
pos->id()==ID_name)
882 final_base_name+=
pos->get_string(ID_identifier);
883 else if(
pos->id()==ID_template_args)
885 else if(
pos->id()==
"::")
899 std::cout <<
"X: " << id_set.size() <<
'\n';
927 <<
"scope '" << final_base_name <<
"' not found" <<
messaget::eom;
930 else if(id_set.size()>=2)
939 assert(id_set.size()==1);
953 final_base_name.clear();
955 else if(
pos->id()==ID_operator)
957 final_base_name+=
"operator";
959 irept::subt::const_iterator next=
pos+1;
960 assert(next != cpp_name.
get_sub().end());
963 next->id() == ID_cpp_name || next->id() == ID_pointer ||
964 next->id() == ID_int || next->id() == ID_char ||
965 next->id() == ID_c_bool || next->id() == ID_merged_type)
970 op_name.
swap(next_ir);
977 final_base_name+=
pos->id_string();
982 base_name=final_base_name;
1002 std::set<irep_idt> primary_templates;
1004 for(
const auto &id_ptr : id_set)
1006 const irep_idt id = id_ptr->identifier;
1014 if(!specialization_of.
empty())
1015 primary_templates.insert(specialization_of);
1017 primary_templates.insert(
id);
1020 assert(!primary_templates.empty());
1022 if(primary_templates.size()>=2)
1031 const symbolt &primary_template_symbol=
1044 full_template_args_tc=
1047 primary_template_symbol,
1048 full_template_args);
1050 for(
auto &arg : full_template_args_tc.
arguments())
1052 if(arg.id() == ID_type)
1054 if(arg.id() == ID_symbol)
1074 std::vector<matcht> matches;
1078 matcht(full_template_args_tc, full_template_args_tc,
1079 primary_template_symbol.
name));
1081 for(
const auto &id_ptr : id_set)
1083 const irep_idt id = id_ptr->identifier;
1104 assert(full_template_args_tc.
arguments().size()==
1105 partial_specialization_args.
arguments().size());
1113 if(template_scope==
nullptr)
1117 <<
"class template instantiation error"
1125 for(std::size_t i=0; i<full_template_args_tc.
arguments().size(); i++)
1127 if(full_template_args_tc.
arguments()[i].id()==ID_type)
1129 full_template_args_tc.
arguments()[i].type());
1148 primary_template_symbol,
1149 partial_specialization_args);
1153 assert(partial_specialization_args_tc.
arguments().size()==
1154 full_template_args_tc.
arguments().size());
1156 if(partial_specialization_args_tc==
1157 full_template_args_tc)
1159 matches.push_back(
matcht(
1160 guessed_template_args, full_template_args_tc,
id));
1165 assert(!matches.empty());
1167 std::sort(matches.begin(), matches.end());
1170 for(std::vector<matcht>::const_iterator
1171 m_it=matches.begin();
1172 m_it!=matches.end();
1175 std::cout <<
"M: " << m_it->cost
1176 <<
" " << m_it->id <<
'\n';
1182 const matcht &match=*matches.begin();
1196 if(instance.
type.
id()!=ID_struct)
1249 else if(id_set.size()==1)
1268 for(
const auto &id_expr : identifiers)
1272 if(id_expr.id()==ID_type)
1280 if(id_expr.type().get_bool(ID_is_template))
1283 if(id_expr.id()==ID_member)
1288 else if(id_expr.id() == ID_pod_constructor)
1290 out <<
"constructor ";
1293 else if(id_expr.id()==ID_template_function_instance)
1303 if(id_expr.type().get_bool(ID_is_template))
1306 else if(id_expr.type().id()==ID_code)
1312 out <<
" " <<
id <<
"(";
1316 for(
const auto ¶meter : parameters)
1318 const typet ¶meter_type = parameter.type();
1330 if(!parameters.empty())
1340 if(id_expr.id()==ID_symbol)
1343 out <<
" (" << symbol.
location <<
")";
1345 else if(id_expr.id()==ID_template_function_instance)
1349 out <<
" (" << symbol.
location <<
")";
1361 bool fail_with_exception)
1374 std::cout <<
"base name: " << base_name <<
'\n';
1375 std::cout <<
"template args: " << template_args.
pretty() <<
'\n';
1387 return do_builtin(base_name, fargs, template_args);
1391 if(base_name==
"__func__" ||
1392 base_name==
"__FUNCTION__" ||
1393 base_name==
"__PRETTY_FUNCTION__")
1399 return std::move(s);
1408 if(template_args.
is_nil())
1420 id_set.insert(&builtin_id);
1436 if(!fail_with_exception)
1470 bool have_classes=
false, have_methods=
false;
1472 for(
const auto &id_ptr : id_set)
1474 const irep_idt id = id_ptr->identifier;
1483 if(want==
wantt::BOTH && have_classes && have_methods)
1485 if(!fail_with_exception)
1502 identifiers.push_back(
exprt(ID_type, instance));
1508 id_set, fargs, identifiers);
1511 identifiers, template_args, fargs);
1517 id_set, fargs, identifiers);
1524 filter(identifiers, want);
1527 std::cout <<
"P0 " << base_name <<
" " << identifiers.size() <<
'\n';
1540 std::cout <<
"P1 " << base_name <<
" " << new_identifiers.size() <<
'\n';
1549 std::cout <<
"P2 " << base_name <<
" " << new_identifiers.size() <<
'\n';
1555 if(new_identifiers.empty())
1557 new_identifiers=identifiers;
1559 if(template_args.
is_nil())
1563 if(new_identifiers.empty())
1564 new_identifiers=identifiers;
1570 std::cout <<
"P3 " << base_name <<
" " << new_identifiers.size() <<
'\n';
1579 std::cout <<
"P4 " << base_name <<
" " << new_identifiers.size() <<
'\n';
1584 if(new_identifiers.size()==1)
1586 result=*new_identifiers.begin();
1591 if(!fail_with_exception)
1594 if(new_identifiers.empty())
1598 <<
"found no match for symbol '" << base_name <<
"', candidates are:\n";
1605 <<
"symbol '" << base_name <<
"' does not uniquely resolve:\n";
1609 exprt e1=*new_identifiers.begin();
1610 exprt e2=*(++new_identifiers.begin());
1613 <<
"e1.type==e2.type: " << (e1.
type() == e2.
type()) <<
'\n';
1615 <<
"e1.id()==e2.id(): " << (e1.
id() == e2.
id()) <<
'\n';
1617 <<
"e1.iden==e2.iden: "
1618 << (e1.
get(ID_identifier) == e2.
get(ID_identifier)) <<
'\n';
1628 for(
const auto &op : fargs.
operands)
1645 if(result.
get_bool(ID_C_not_accessible))
1648 if(!fail_with_exception)
1653 <<
"error: member '" << result.
get(ID_component_name)
1654 <<
"' is not accessible";
1664 if(!fail_with_exception)
1670 <<
"error: expected expression, but got type '"
1678 if(result.
id()!=ID_type)
1680 if(!fail_with_exception)
1686 <<
"error: expected type, but got expression '"
1701 const exprt &template_expr,
1702 const exprt &desired_expr)
1704 if(template_expr.
id()==ID_cpp_name)
1721 for(
const auto &id_ptr : id_set)
1729 if(e.
id()==ID_unassigned)
1741 const typet &template_type,
1742 const typet &desired_type)
1775 std::cout <<
"TT: " << template_type.
pretty() <<
'\n';
1776 std::cout <<
"DT: " << desired_type.
pretty() <<
'\n';
1779 if(template_type.
id()==ID_cpp_name)
1806 for(
const auto &id_ptr : id_set)
1815 if(t.
id()==ID_unassigned)
1823 std::cout <<
"ASSIGN " <<
id.identifier <<
" := "
1832 else if(template_type.
id()==ID_merged_type)
1845 else if(template_type.
id()==ID_pointer)
1847 if(desired_type.
id() == ID_pointer)
1850 else if(template_type.
id()==ID_array)
1852 if(desired_type.
id() == ID_array)
1875 assert(expr.
id()==ID_symbol);
1895 const symbolt &template_symbol=
1912 if(function_declarator.
type().
id()!=ID_function_type)
1916 <<
"expected function type for function template"
1928 if(template_scope==
nullptr)
1932 << template_identifier <<
'\n'
1933 <<
"function template instantiation error"
1945 exprt::operandst::const_iterator it=fargs.
operands.begin();
1946 for(
const auto ¶meter : parameters)
1951 if(parameter.id()==ID_cpp_declaration)
1962 merge_type(arg_declaration.
type());
1986 typet function_type=
1993 function_type.
set(ID_C_template, template_symbol.
name);
1994 function_type.
set(ID_C_template_arguments, template_args);
1998 exprt template_function_instance(
1999 ID_template_function_instance, function_type);
2001 return template_function_instance;
2009 if(expr.
id()!=ID_symbol)
2012 const symbolt &template_symbol =
2019 if(template_args_non_tc.
is_nil())
2040 template_args_non_tc);
2087 fargs.
operands.begin()->type().get(ID_identifier));
2089 assert(type_symb.
type.
id()==ID_struct);
2095 "method should exist in struct");
2114 unsigned &args_distance,
2124 if(expr.
id()==ID_member ||
2141 object.set(ID_C_lvalue,
true);
2151 fargs.
operands.size() == parameters.size())
2183 for(
const auto &id_ptr : id_set)
2187 if(
id.is_class() ||
id.is_enum() ||
id.is_namespace())
2190 assert(
id.is_scope);
2191 new_set.insert(&
id);
2193 else if(
id.is_typedef())
2207 if(symbol.
type.
id()==ID_struct)
2214 new_set.insert(&class_id);
2229 if(symbol.
type.
id() == ID_struct)
2231 id.print(std::cout);
2232 assert(
id.is_scope);
2233 new_set.insert(&
id);
2252 std::cout <<
"E: " << e.
pretty() <<
'\n';
2258 if(e.
type().
id() == ID_template_parameter_symbol_type)
2264 irep_idt identifier=type.get_identifier();
2269 if(symbol.
type.
id() == ID_template_parameter_symbol_type)
2271 else if(symbol.
type.
id()==ID_struct ||
2272 symbol.
type.
id()==ID_union ||
2273 symbol.
type.
id()==ID_c_enum)
2280 new_set.insert(&class_id);
2290 id_set.swap(new_set);
2297 for(cpp_scopest::id_sett::iterator
2302 if((*it)->is_namespace())
2306 cpp_scopest::id_sett::iterator old(it);
2319 for(
const auto &arg : fargs.
operands)
2323 if(final_type.
id()!=ID_struct && final_type.
id()!=ID_union)
2329 id_set.insert(tmp_set.begin(), tmp_set.end());