void c_typecheck_baset::typecheck_code(codet &code) { if(code.id()!=ID_code) { err_location(code); error() << "expected code, got " << code.pretty() << eom; throw 0; } code.type()=code_typet(); const irep_idt &statement=code.get_statement(); if(statement==ID_expression) typecheck_expression(code); else if(statement==ID_label) typecheck_label(to_code_label(code)); else if(statement==ID_switch_case) typecheck_switch_case(to_code_switch_case(code)); else if(statement==ID_gcc_switch_case_range) typecheck_gcc_switch_case_range(code); else if(statement==ID_block) typecheck_block(code); else if(statement==ID_decl_block) { } else if(statement==ID_ifthenelse) typecheck_ifthenelse(to_code_ifthenelse(code)); else if(statement==ID_while) typecheck_while(to_code_while(code)); else if(statement==ID_dowhile) typecheck_dowhile(to_code_dowhile(code)); else if(statement==ID_for) typecheck_for(code); else if(statement==ID_switch) typecheck_switch(to_code_switch(code)); else if(statement==ID_break) typecheck_break(code); else if(statement==ID_goto) typecheck_goto(to_code_goto(code)); else if(statement==ID_gcc_computed_goto) typecheck_gcc_computed_goto(code); else if(statement==ID_continue) typecheck_continue(code); else if(statement==ID_return) typecheck_return(code); else if(statement==ID_decl) typecheck_decl(code); else if(statement==ID_assign) typecheck_assign(code); else if(statement==ID_skip) { } else if(statement==ID_asm) typecheck_asm(code); else if(statement==ID_start_thread) typecheck_start_thread(code); else if(statement==ID_gcc_local_label) typecheck_gcc_local_label(code); else if(statement==ID_msc_try_finally) { assert(code.operands().size()==2); typecheck_code(to_code(code.op0())); typecheck_code(to_code(code.op1())); } else if(statement==ID_msc_try_except) { assert(code.operands().size()==3); typecheck_code(to_code(code.op0())); typecheck_expr(code.op1()); typecheck_code(to_code(code.op2())); } else if(statement==ID_msc_leave) { // fine as is, but should check that we // are in a 'try' block } else if(statement==ID_static_assert) { assert(code.operands().size()==2); typecheck_expr(code.op0()); typecheck_expr(code.op1()); } else if(statement==ID_CPROVER_try_catch || statement==ID_CPROVER_try_finally) { assert(code.operands().size()==2); typecheck_code(to_code(code.op0())); typecheck_code(to_code(code.op1())); } else if(statement==ID_CPROVER_throw) { assert(code.operands().empty()); } else if(statement==ID_assume || statement==ID_assert) { // These are not generated by the C/C++ parsers, // but we allow them for the benefit of other users // of the typechecker. assert(code.operands().size()==1); typecheck_expr(code.op0()); } else { err_location(code); error() << "unexpected statement: " << statement << eom; throw 0; } }