void cpp_declarationt::name_anon_struct_union(typet &dest) { // We name any anon struct/unions according to the first // declarator. No need to do anon enums, which get // a name based on the enum elements. if(dest.id()==ID_struct || dest.id()==ID_union) { if(dest.find(ID_tag).is_nil()) { // it's anonymous const declaratorst &d=declarators(); if(!d.empty() && d.front().name().is_simple_name()) { // Anon struct/unions without declarator are pretty // useless, but still possible. irep_idt base_name="anon-"+id2string(d.front().name().get_base_name()); dest.set(ID_tag, cpp_namet(base_name)); dest.set(ID_C_is_anonymous, true); } } } else if(dest.id()==ID_merged_type) { Forall_subtypes(it, dest) name_anon_struct_union(*it); } }
cpp_scopet &cpp_typecheckt::typecheck_template_parameters( template_typet &type) { cpp_save_scopet cpp_saved_scope(cpp_scopes); assert(type.id()==ID_template); std::string id_suffix="template::"+i2string(template_counter++); // produce a new scope for the template parameters cpp_scopet &template_scope= cpp_scopes.current_scope().new_scope( cpp_scopes.current_scope().prefix+id_suffix); template_scope.prefix=template_scope.get_parent().prefix+id_suffix; template_scope.id_class=cpp_idt::TEMPLATE_SCOPE; cpp_scopes.go_to(template_scope); // put template parameters into this scope template_typet::template_parameterst ¶meters= type.template_parameters(); unsigned anon_count=0; for(template_typet::template_parameterst::iterator it=parameters.begin(); it!=parameters.end(); it++) { exprt ¶meter=*it; cpp_declarationt declaration; declaration.swap(static_cast<cpp_declarationt &>(parameter)); cpp_declarator_convertert cpp_declarator_converter(*this); // there must be _one_ declarator assert(declaration.declarators().size()==1); cpp_declaratort &declarator=declaration.declarators().front(); // it may be anonymous if(declarator.name().is_nil()) { irept name(ID_name); name.set(ID_identifier, "anon#"+i2string(++anon_count)); declarator.name()=cpp_namet(); declarator.name().get_sub().push_back(name); } #if 1 // The declarator needs to be just a name if(declarator.name().get_sub().size()!=1 || declarator.name().get_sub().front().id()!=ID_name) { err_location(declaration); throw "template parameter must be simple name"; } cpp_scopet &scope=cpp_scopes.current_scope(); irep_idt base_name=declarator.name().get_sub().front().get(ID_identifier); irep_idt identifier=scope.prefix+id2string(base_name); // add to scope cpp_idt &id=scope.insert(base_name); id.identifier=identifier; id.id_class=cpp_idt::TEMPLATE_PARAMETER; // is it a type or not? if(declaration.get_bool(ID_is_type)) { parameter=exprt(ID_type, typet(ID_symbol)); parameter.type().set(ID_identifier, identifier); parameter.type().add_source_location()=declaration.find_source_location(); } else { // The type is not checked, as it might depend // on earlier parameters. typet type=declaration.type(); parameter=symbol_exprt(identifier, type); } // There might be a default type or default value. // We store it for later, as it can't be typechecked now // because of possible dependencies on earlier parameters! if(declarator.value().is_not_nil()) parameter.add(ID_C_default_value)=declarator.value(); #else // is it a type or not? cpp_declarator_converter.is_typedef=declaration.get_bool(ID_is_type); // say it a template parameter cpp_declarator_converter.is_template_parameter=true; // There might be a default type or default value. // We store it for later, as it can't be typechecked now // because of possible dependencies on earlier parameters! exprt default_value=declarator.value(); declarator.value().make_nil(); const symbolt &symbol= cpp_declarator_converter.convert(declaration, declarator); if(cpp_declarator_converter.is_typedef) { parameter=exprt(ID_type, typet(ID_symbol)); parameter.type().set(ID_identifier, symbol.name); parameter.type().add_source_location()=declaration.find_location(); } else parameter=symbol.symbol_expr(); // set (non-typechecked) default value if(default_value.is_not_nil()) parameter.add(ID_C_default_value)=default_value; parameter.add_source_location()=declaration.find_location(); #endif } // continue without adding to the prefix template_scope.prefix=template_scope.get_parent().prefix; return template_scope; }