void c_typecheck_baset::typecheck_new_symbol(symbolt &symbol) { if(symbol.is_parameter) adjust_function_parameter(symbol.type); // check initializer, if needed if(symbol.type.id()==ID_code) { if(symbol.value.is_not_nil() && !symbol.is_macro) typecheck_function_body(symbol); else { // we don't need the identifiers code_typet &code_type=to_code_type(symbol.type); for(code_typet::parameterst::iterator it=code_type.parameters().begin(); it!=code_type.parameters().end(); it++) it->set_identifier(irep_idt()); } } else { // check the initializer do_initializer(symbol); } }
void c_typecheck_baset::typecheck_new_symbol(symbolt &symbol) { if(symbol.is_parameter) adjust_function_parameter(symbol.type); // check initializer, if needed if(symbol.type.id()==ID_code) { if(symbol.value.is_not_nil()) typecheck_function_body(symbol); else { // we don't need the identifiers code_typet &code_type=to_code_type(symbol.type); for(code_typet::parameterst::iterator it=code_type.parameters().begin(); it!=code_type.parameters().end(); it++) it->set_identifier(irep_idt()); } } else { if(symbol.type.id()==ID_array && to_array_type(symbol.type).size().is_nil() && !symbol.is_type) { // Insert a new type symbol for the array. // We do this because we want a convenient way // of adjusting the size of the type later on. type_symbolt new_symbol(symbol.type); new_symbol.name=id2string(symbol.name)+"$type"; new_symbol.base_name=id2string(symbol.base_name)+"$type"; new_symbol.location=symbol.location; new_symbol.mode=symbol.mode; new_symbol.module=symbol.module; symbol.type=symbol_typet(new_symbol.name); symbolt *new_sp; symbol_table.move(new_symbol, new_sp); } // check the initializer do_initializer(symbol); } }
void c_typecheck_baset::typecheck_code_type(code_typet &type) { // the return type is still 'subtype()' type.return_type()=type.subtype(); type.remove_subtype(); code_typet::parameterst ¶meters=type.parameters(); // if we don't have any parameters, we assume it's (...) if(parameters.empty()) { type.make_ellipsis(); } else // we do have parameters { // is the last one ellipsis? if(type.parameters().back().id()==ID_ellipsis) { type.make_ellipsis(); type.parameters().pop_back(); } parameter_map.clear(); for(auto ¶m : type.parameters()) { // turn the declarations into parameters if(param.id()==ID_declaration) { ansi_c_declarationt &declaration= to_ansi_c_declaration(param); code_typet::parametert parameter; // first fix type typet &type=parameter.type(); type=declaration.full_type(declaration.declarator()); std::list<codet> tmp_clean_code; tmp_clean_code.swap(clean_code); // ignore side-effects typecheck_type(type); tmp_clean_code.swap(clean_code); adjust_function_parameter(type); // adjust the identifier irep_idt identifier=declaration.declarator().get_name(); // abstract or not? if(identifier==irep_idt()) { // abstract parameter.add_source_location()=declaration.type().source_location(); } else { // make visible now, later parameters might use it parameter_map[identifier]=type; parameter.set_base_name(declaration.declarator().get_base_name()); parameter.add_source_location()= declaration.declarator().source_location(); } // put the parameter in place of the declaration param.swap(parameter); } } parameter_map.clear(); if(parameters.size()==1 && follow(parameters[0].type()).id()==ID_empty) { // if we just have one parameter of type void, remove it parameters.clear(); } } typecheck_type(type.return_type()); // 6.7.6.3: // "A function declarator shall not specify a return type that // is a function type or an array type." const typet &return_type=follow(type.return_type()); if(return_type.id()==ID_array) { error().source_location=type.source_location(); error() << "function must not return array" << eom; throw 0; } if(return_type.id()==ID_code) { error().source_location=type.source_location(); error() << "function must not return function type" << eom; throw 0; } }
void c_typecheck_baset::typecheck_code_type(code_typet &type) { code_typet::parameterst ¶meters=type.parameters(); // if we don't have any parameters, we assume it's (...) if(parameters.empty()) { type.make_ellipsis(); } else { // we do have parameters parameter_map.clear(); for(unsigned i=0; i<type.parameters().size(); i++) { code_typet::parametert ¶meter=type.parameters()[i]; // first fix type typet &type=parameter.type(); typecheck_type(type); adjust_function_parameter(type); // adjust the identifier irep_idt identifier=parameter.get_identifier(); if(identifier!=irep_idt()) { identifier=add_language_prefix(identifier); id_replace_mapt::const_iterator m_it=id_replace_map.find(identifier); if(m_it!=id_replace_map.end()) identifier=m_it->second; parameter.set_identifier(identifier); // make visible now, later parameters might use it parameter_map[identifier]=type; } } parameter_map.clear(); if(parameters.size()==1 && follow(parameters[0].type()).id()==ID_empty) { // if we just have one parameter of type void, remove it parameters.clear(); } } typecheck_type(type.return_type()); // 6.7.6.3: // "A function declarator shall not specify a return type that // is a function type or an array type." const typet &return_type=follow(type.return_type()); if(return_type.id()==ID_array) { err_location(type); throw "function must not return array"; } if(return_type.id()==ID_code) { err_location(type); throw "function must not return function type"; } }