32 for(std::size_t i=0; i<new_parameters.size(); i++)
34 if(i<old_parameters.size() &&
35 old_parameters[i].has_default_argument() &&
36 !new_parameters[i].has_default_argument())
39 new_parameters[i].default_argument()=old_parameters[i].default_argument();
57 static_cast<const cpp_namet &>(type.find(ID_tag));
62 error() <<
"class templates must not be anonymous" <<
eom;
69 error() <<
"simple name expected as class template tag" <<
eom;
80 base_name, template_type, partial_specialization_args);
90 cpp_scopet::TEMPLATE);
94 const symbolt &previous=
lookup((*id_set.begin())->identifier);
95 if(previous.
name!=symbol_name || id_set.
size()>1)
98 str <<
"template declaration of `" << base_name.
c_str()
99 <<
" does not match previous declaration\n";
100 str <<
"location of previous definition: " << previous.
location;
112 symbolt &previous_symbol=*maybe_symbol;
116 bool previous_has_body=
120 if(has_body && previous_has_body)
123 error() <<
"template struct `" << base_name
124 <<
"' defined previously\n"
125 <<
"location of previous definition: "
138 previous_symbol.
type.
swap(declaration);
141 std::cout <<
"*****\n";
143 std::cout <<
"*****\n";
144 std::cout <<
"II: " << symbol_name <<
'\n';
170 symbol.
name=symbol_name;
186 error() <<
"cpp_typecheckt::typecheck_compound_type: "
187 <<
"symbol_table.move() failed"
211 const cpp_namet &cpp_name = declarator.name();
221 error() <<
"function template must have simple name" <<
eom;
230 declarator.merge_type(declaration.
type());
240 bool has_value=declarator.find(ID_value).is_not_nil();
244 symbol_tablet::symbolst::const_iterator previous_symbol=
249 bool previous_has_value =
253 if(has_value && previous_has_value)
256 error() <<
"function template symbol `" << base_name
257 <<
"' declared previously\n"
258 <<
"location of previous definition: "
259 << previous_symbol->second.location <<
eom;
275 symbol.
name=symbol_name;
290 error() <<
"cpp_typecheckt::typecheck_compound_type: "
291 <<
"symbol_table.move() failed"
314 const cpp_namet &cpp_name = declarator.name();
321 if(cpp_name.
get_sub().size()==4 &&
322 cpp_name.
get_sub()[0].id()==ID_name &&
323 cpp_name.
get_sub()[1].id()==ID_template_args &&
324 cpp_name.
get_sub()[2].id()==
"::" &&
325 cpp_name.
get_sub()[3].id()==ID_name)
328 else if(cpp_name.
get_sub().size()==5 &&
329 cpp_name.
get_sub()[0].id()==ID_name &&
330 cpp_name.
get_sub()[1].id()==ID_template_args &&
331 cpp_name.
get_sub()[2].id()==
"::" &&
332 cpp_name.
get_sub()[3].id()==ID_operator)
341 error() <<
"bad template name" <<
eom;
348 cpp_name.
get_sub().front().get(ID_identifier),
356 error() <<
"class template `"
357 << cpp_name.
get_sub().front().get(ID_identifier)
358 <<
"' not found" <<
eom;
361 else if(id_set.size()>1)
364 error() <<
"class template `"
365 << cpp_name.
get_sub().front().get(ID_identifier)
366 <<
"' is ambiguous" <<
eom;
373 error() <<
"class template `"
374 << cpp_name.
get_sub().front().get(ID_identifier)
375 <<
"' is not a template" <<
eom;
379 const cpp_idt &cpp_id=**(id_set.begin());
383 exprt &template_methods =
384 static_cast<exprt &>(template_symbol.
value.
add(ID_template_methods));
391 const irept &instantiated_with =
392 template_symbol.
value.
add(ID_instantiated_with);
394 for(std::size_t i=0; i<instantiated_with.
get_sub().size(); i++)
397 static_cast<const cpp_template_args_tct &>(
398 instantiated_with.
get_sub()[i]);
412 decl_tmp.remove(ID_template_type);
413 decl_tmp.remove(ID_is_template);
425 std::string identifier=
433 for(template_typet::template_parameterst::const_iterator
441 if(it->id()==ID_type)
451 if(!partial_specialization_args.
arguments().empty())
453 identifier+=
"_specialized_to_<";
456 for(cpp_template_args_non_tct::argumentst::const_iterator
457 it=partial_specialization_args.
arguments().begin();
458 it!=partial_specialization_args.
arguments().end();
467 if(it->id() == ID_type || it->id() == ID_ambiguous)
482 const typet &function_type)
486 std::string identifier=
488 partial_specialization_args);
503 assert(type.
id()==ID_struct);
506 static_cast<cpp_namet &>(type.
add(ID_tag));
508 if(cpp_name.is_qualified())
511 error() <<
"qualifiers not expected here" <<
eom;
515 if(cpp_name.get_sub().size()!=2 ||
516 cpp_name.get_sub()[0].id()!=ID_name ||
517 cpp_name.get_sub()[1].id()!=ID_template_args)
522 error() <<
"bad template-class-specialization name" <<
eom;
527 cpp_name.get_sub()[0].get(ID_identifier);
542 for(cpp_scopest::id_sett::iterator
547 cpp_scopest::id_sett::iterator next=it;
550 if(
lookup((*it)->identifier).type.find(ID_specialization_of).is_not_nil())
560 error() <<
"class template `" << base_name <<
"' not found" <<
eom;
563 else if(id_set.size()>1)
566 error() <<
"class template `" << base_name <<
"' is ambiguous"
571 symbol_tablet::symbolst::const_iterator s_it=
576 const symbolt &template_symbol=s_it->second;
578 if(!template_symbol.type.get_bool(ID_is_template))
581 error() <<
"expected a template" <<
eom;
593 template_args_non_tc);
598 cpp_name.source_location(),
621 declaration.
declarators().front().type().id()!=ID_function_type)
624 error() <<
"expected function template specialization" <<
eom;
635 assert(!cpp_name.
get_sub().empty());
637 if(cpp_name.
get_sub().back().id()==ID_template_args)
640 if(cpp_name.
get_sub().size()!=2 ||
641 cpp_name.
get_sub()[0].id()!=ID_name ||
642 cpp_name.
get_sub()[1].id()!=ID_template_args)
647 error() <<
"bad template-function-specialization name" <<
eom;
651 std::string base_name=
652 cpp_name.
get_sub()[0].get(ID_identifier).c_str();
660 error() <<
"template function `" << base_name <<
"' not found"
664 else if(id_set.size()>1)
667 error() <<
"template function `" << base_name
668 <<
"' is ambiguous" <<
eom;
672 const symbolt &template_symbol=
673 lookup((*id_set.begin())->identifier);
683 typet specialization;
684 specialization.
swap(declarator);
700 new_declaration.
remove(ID_template_type);
701 new_declaration.
remove(ID_is_template);
702 new_declaration.
set(ID_C_template,
"");
713 assert(type.
id()==ID_template);
731 unsigned anon_count=0;
733 for(template_typet::template_parameterst::iterator
734 it=parameters.begin();
735 it!=parameters.end();
738 exprt ¶meter=*it;
741 declaration.
swap(static_cast<cpp_declarationt &>(parameter));
751 if(declarator.name().is_nil())
756 if(declarator.name().get_sub().size()!=1 ||
757 declarator.name().get_sub().front().id()!=ID_name)
760 error() <<
"template parameter must be simple name" <<
eom;
766 irep_idt base_name=declarator.name().get_sub().front().get(ID_identifier);
775 if(declaration.
get_bool(ID_is_type))
790 if(declarator.value().is_not_nil())
791 parameter.
add(ID_C_default_value)=declarator.value();
803 exprt default_value=declarator.value();
807 cpp_declarator_converter.
convert(declaration, declarator);
819 parameter.
add(ID_C_default_value)=default_value;
828 return template_scope;
835 const symbolt &template_symbol,
839 assert(template_args.
id()!=ID_already_typechecked);
854 template_type.template_parameters();
856 if(parameters.size()<args.size())
859 error() <<
"too many template arguments (expected "
860 << parameters.size() <<
", but got "
861 << args.size() <<
")" <<
eom;
870 for(std::size_t i=0; i<parameters.size(); i++)
882 error() <<
"not enough template arguments (expected "
883 << parameters.size() <<
", but got " << args.size()
898 assert(i<args.size());
902 if(parameter.
id()==ID_type)
904 if(arg.id()==ID_type)
908 else if(arg.id() == ID_ambiguous)
912 arg=
exprt(ID_type, t);
917 error() <<
"expected type, but got expression" <<
eom;
923 if(arg.id()==ID_type)
926 error() <<
"expected expression, but got type" <<
eom;
929 else if(arg.id() == ID_ambiguous)
945 template_scope!=
nullptr,
947 "template_scope is null");
969 assert(args.size()==parameters.size());
982 error() <<
"invalid use of 'virtual' in template declaration"
990 error() <<
"template declaration for typedef" <<
eom;
1008 error() <<
"class template not expected to have declarators"
1014 if(type.
id()!=ID_struct)
1017 error() <<
"expected class template" <<
eom;
1024 if((static_cast<const cpp_namet &>(
1025 type.
find(ID_tag))).has_template_args())
1042 error() <<
"non-class template is expected to have a declarator"
1061 const cpp_namet &cpp_name = declarator.name();