void c_typecheck_baset::typecheck_declaration( ansi_c_declarationt &declaration) { if(declaration.get_is_static_assert()) { assert(declaration.operands().size()==2); typecheck_expr(declaration.op0()); typecheck_expr(declaration.op1()); } else { // get storage spec c_storage_spect c_storage_spec(declaration.type()); declaration.set_is_inline(c_storage_spec.is_inline); declaration.set_is_static(c_storage_spec.is_static); declaration.set_is_extern(c_storage_spec.is_extern); declaration.set_is_thread_local(c_storage_spec.is_thread_local); declaration.set_is_register(c_storage_spec.is_register); declaration.set_is_typedef(c_storage_spec.is_typedef); // first typecheck the type of the declaration typecheck_type(declaration.type()); // mark as 'already typechecked' make_already_typechecked(declaration.type()); // Now do declarators, if any. for(ansi_c_declarationt::declaratorst::iterator d_it=declaration.declarators().begin(); d_it!=declaration.declarators().end(); d_it++) { symbolt symbol; declaration.to_symbol(*d_it, symbol); // now check other half of type typecheck_type(symbol.type); typecheck_symbol(symbol); } } }
void c_typecheck_baset::typecheck_declaration( ansi_c_declarationt &declaration) { if(declaration.get_is_static_assert()) { assert(declaration.operands().size()==2); typecheck_expr(declaration.op0()); typecheck_expr(declaration.op1()); } else { // get storage spec c_storage_spect c_storage_spec(declaration.type()); // first typecheck the type of the declaration typecheck_type(declaration.type()); // mark as 'already typechecked' make_already_typechecked(declaration.type()); codet contract; { exprt spec_requires= static_cast<const exprt&>(declaration.find(ID_C_spec_requires)); contract.add(ID_C_spec_requires).swap(spec_requires); exprt spec_ensures= static_cast<const exprt&>(declaration.find(ID_C_spec_ensures)); contract.add(ID_C_spec_ensures).swap(spec_ensures); } // Now do declarators, if any. for(ansi_c_declarationt::declaratorst::iterator d_it=declaration.declarators().begin(); d_it!=declaration.declarators().end(); d_it++) { c_storage_spect full_spec(declaration.full_type(*d_it)); full_spec|=c_storage_spec; declaration.set_is_inline(full_spec.is_inline); declaration.set_is_static(full_spec.is_static); declaration.set_is_extern(full_spec.is_extern); declaration.set_is_thread_local(full_spec.is_thread_local); declaration.set_is_register(full_spec.is_register); declaration.set_is_typedef(full_spec.is_typedef); declaration.set_is_weak(full_spec.is_weak); symbolt symbol; declaration.to_symbol(*d_it, symbol); current_symbol=symbol; // now check other half of type typecheck_type(symbol.type); if(!full_spec.alias.empty()) { if(symbol.value.is_not_nil()) { error().source_location=symbol.location; error() << "alias attribute cannot be used with a body" << eom; throw 0; } // alias function need not have been declared yet, thus // can't lookup symbol.value=symbol_exprt(full_spec.alias); symbol.is_macro=true; } if(full_spec.section.empty()) apply_asm_label(full_spec.asm_label, symbol); else { std::string asm_name; asm_name=id2string(full_spec.section)+"$$"; if(!full_spec.asm_label.empty()) asm_name+=id2string(full_spec.asm_label); else asm_name+=id2string(symbol.name); apply_asm_label(asm_name, symbol); } irep_idt identifier=symbol.name; d_it->set_name(identifier); typecheck_symbol(symbol); // add code contract (if any); we typecheck this after the // function body done above, so as to have parameter symbols // available symbol_tablet::symbolst::iterator s_it= symbol_table.symbols.find(identifier); assert(s_it!=symbol_table.symbols.end()); symbolt &new_symbol=s_it->second; typecheck_spec_expr(contract, ID_C_spec_requires); typet ret_type=empty_typet(); if(new_symbol.type.id()==ID_code) ret_type=to_code_type(new_symbol.type).return_type(); assert(parameter_map.empty()); if(ret_type.id()!=ID_empty) parameter_map["__CPROVER_return_value"]=ret_type; typecheck_spec_expr(contract, ID_C_spec_ensures); parameter_map.clear(); if(contract.find(ID_C_spec_requires).is_not_nil()) new_symbol.type.add(ID_C_spec_requires)= contract.find(ID_C_spec_requires); if(contract.find(ID_C_spec_ensures).is_not_nil()) new_symbol.type.add(ID_C_spec_ensures)= contract.find(ID_C_spec_ensures); } } }