symbolt &cpp_declarator_convertert::convert( const typet &declaration_type, const cpp_storage_spect &storage_spec, const cpp_member_spect &member_spec, cpp_declaratort &declarator) { assert(declaration_type.is_not_nil()); if(declaration_type.id()=="cpp-cast-operator") { typet type; type.swap(declarator.name().get_sub().back()); declarator.type().subtype()=type; std::string tmp; cpp_typecheck.typecheck_type(type); irept name(ID_name); name.set(ID_identifier, "("+cpp_type2name(type)+")"); declarator.name().get_sub().back().swap(name); } assert(declarator.id()==ID_cpp_declarator); final_type=declarator.merge_type(declaration_type); assert(final_type.is_not_nil()); cpp_template_args_non_tct template_args; // run resolver on scope { cpp_save_scopet save_scope(cpp_typecheck.cpp_scopes); cpp_typecheck_resolvet cpp_typecheck_resolve(cpp_typecheck); cpp_typecheck_resolve.resolve_scope( declarator.name(), base_name, template_args); scope=&cpp_typecheck.cpp_scopes.current_scope(); // check the declarator-part of the type, in that scope cpp_typecheck.typecheck_type(final_type); } is_code=is_code_type(final_type); // global-scope arrays must have fixed size if(scope->is_global_scope()) cpp_typecheck.check_fixed_size_array(final_type); get_final_identifier(); // first see if it is a member if(scope->id_class==cpp_idt::CLASS && !is_friend) { // it's a member! it must be declared already typet &method_qualifier= static_cast<typet &>(declarator.method_qualifier()); // adjust template type if(final_type.id()==ID_template) { assert(0); typet tmp; tmp.swap(final_type.subtype()); final_type.swap(tmp); } // try static first symbol_tablet::symbolst::iterator c_it= cpp_typecheck.symbol_table.symbols.find(final_identifier); if(c_it==cpp_typecheck.symbol_table.symbols.end()) { // adjust type if it's a non-static member function if(final_type.id()==ID_code) cpp_typecheck.adjust_method_type( scope->identifier, final_type, method_qualifier); get_final_identifier(); // try again c_it=cpp_typecheck.symbol_table.symbols.find(final_identifier); if(c_it==cpp_typecheck.symbol_table.symbols.end()) { cpp_typecheck.err_location(declarator.name()); cpp_typecheck.str << "member `" << base_name << "' not found in scope `" << scope->identifier << "'"; throw 0; } } assert(c_it!=cpp_typecheck.symbol_table.symbols.end()); symbolt &symbol=c_it->second; combine_types(declarator.name().source_location(), final_type, symbol); enforce_rules(symbol); // If it is a constructor, we take care of the // object initialization if(final_type.get(ID_return_type)==ID_constructor) { const cpp_namet &name=declarator.name(); exprt symbol_expr= cpp_typecheck.resolve( name, cpp_typecheck_resolvet::TYPE, cpp_typecheck_fargst()); if(symbol_expr.id()!=ID_type || symbol_expr.type().id()!=ID_symbol) { cpp_typecheck.err_location(name.source_location()); cpp_typecheck.str << "error: expected type"; throw 0; } irep_idt identifier=symbol_expr.type().get(ID_identifier); const symbolt &symb=cpp_typecheck.lookup(identifier); const typet &type = symb.type; assert(type.id()==ID_struct); if(declarator.find(ID_member_initializers).is_nil()) declarator.set(ID_member_initializers, ID_member_initializers); cpp_typecheck.check_member_initializers( type.find(ID_bases), to_struct_type(type).components(), declarator.member_initializers()); cpp_typecheck.full_member_initialization( to_struct_type(type), declarator.member_initializers()); } if(!storage_spec.is_extern()) symbol.is_extern=false; // initializer? handle_initializer(symbol, declarator); return symbol; } else { // no, it's no way a method // we won't allow the constructor/destructor type if(final_type.id()==ID_code && to_code_type(final_type).return_type().id()==ID_constructor) { cpp_typecheck.err_location(declarator.name().source_location()); cpp_typecheck.str << "function must have return type"; throw 0; } // already there? symbol_tablet::symbolst::iterator c_it= cpp_typecheck.symbol_table.symbols.find(final_identifier); if(c_it==cpp_typecheck.symbol_table.symbols.end()) return convert_new_symbol(storage_spec, member_spec, declarator); symbolt &symbol=c_it->second; if(!storage_spec.is_extern()) symbol.is_extern = false; if(declarator.get_bool("#template_case")) return symbol; combine_types(declarator.name().source_location(), final_type, symbol); enforce_rules(symbol); // initializer? handle_initializer(symbol, declarator); if(symbol.type.id()=="cpp-template-type") { cpp_scopet::id_sett id_set; scope->lookup_identifier(symbol.name, cpp_idt::TEMPLATE_PARAMETER, id_set); if(id_set.empty()) { cpp_idt &identifier= cpp_typecheck.cpp_scopes.put_into_scope(symbol,*scope); identifier.id_class=cpp_idt::TEMPLATE_PARAMETER; } } return symbol; } }
static inline int generate_external_arglist (int *argc, struct FIAL_value ***argvp, node *arglist, struct FIAL_value **arguments, exec_env *env) { /*FIXME: make it so the parser counts how many arguments there * are.*/ int result = 0; int count = 0; node *iter; int i, res; int tmp; value ref; value *arg_strip = NULL; (*argvp) = NULL; /* for(count = 0, iter = arglist; iter != NULL; iter = iter->right) count++; *argc = count; */ if(arglist) { assert(arglist->n); *argc = count = arglist->n; arglist = arglist->left; arg_strip = calloc(sizeof(*arg_strip), count); *arguments = arg_strip; } if(count) { (*argvp) = malloc(sizeof(struct FIAL_value *) * count); /* no need to initialize.... */ if(!(*argvp)) { result = -1; goto error; } for(i = 0, iter = arglist; i < count; i++, iter = iter->right) { value val; memset(&val, 0, sizeof(val)); assert(iter); switch(iter->type) { case AST_ARGLIST_ID: assert(iter->sym); tmp = get_ref_from_sym_block_stack(&val, iter->sym, env->block_stack); if(tmp == 1) { result = -2; goto error; } assert(val.type == VALUE_REF); (*argvp)[i] = val.ref; break; case AST_ARGLIST_EXPR: assert(iter->type == AST_ARGLIST_EXPR); assert(arg_strip); tmp = eval_expression(arg_strip + i, iter->left, env); if(tmp < 0) { result = -3; goto error; } (*argvp)[i] = arg_strip + i; break; case AST_ARGLIST_INIT: assert(iter->type == AST_ARGLIST_INIT); assert(arg_strip); tmp = handle_initializer(arg_strip + i, iter->left, env); if(tmp < 0) { result = -4; goto error; } (*argvp)[i] = arg_strip + i; break; case AST_ARGLIST_MOVE_ID: assert(arg_strip); res = get_ref_from_sym_block_stack(&ref, iter->sym, env->block_stack); if(res == 1) { result = -2; goto error; } FIAL_move_value(arg_strip + i, ref.ref, env->interp); (*argvp)[i] = arg_strip + i; break; case AST_ARGLIST_COPY_ID: assert(arg_strip); res = get_ref_from_sym_block_stack(&ref, iter->sym, env->block_stack); if(res == 1) { result = -2; goto error; } if(FIAL_copy_value(arg_strip + i, ref.ref, env->interp) < 0) { result = -1; goto error; } (*argvp)[i] = arg_strip + i; break; case AST_ARGLIST_MOVE_ACS: assert(iter->left); assert(arg_strip); res = get_ref_from_map_access(&ref, iter->left, env->block_stack); if(res != 0) { result = -5; goto error; } FIAL_move_value(arg_strip + i, ref.ref, env->interp); (*argvp)[i] = arg_strip + i; break; case AST_ARGLIST_COPY_ACS: assert(iter->left); assert(arg_strip); res = get_ref_from_map_access(&ref, iter->left, env->block_stack); if(res != 0) { result = -5; goto error; } if(FIAL_copy_value(arg_strip + i, ref.ref, env->interp) < 0) { result = -1; goto error; } (*argvp)[i] = arg_strip + i; break; default: assert(0); break; } } return 0; } return 1; /* no args... not sure if this matters. */ error: free(*argvp); /* freeing is fine, since expressable values do not have * finilizers. */ free_arg_strip(count, arg_strip, env->interp ); *argvp = NULL; *arguments = NULL; return result; }
static int handle_assign_right (struct FIAL_value *val, struct FIAL_ast_node *node, struct FIAL_exec_env *env) { struct FIAL_value ref; int res; switch (node->type) { case AST_SEQ_INITIALIZER: /* fallthrough */ case AST_MAP_INITIALIZER: if( handle_initializer(val, node, env) < 0) return -1; break; case AST_INIT_MOVE_ID: res = get_ref_from_sym_block_stack(&ref, node->sym, env->block_stack); if (res != 0) { env->error.code = ERROR_UNDECLARED_VAR; env->error.static_msg = "unknown variable in move assignmnet"; FIAL_set_error(env); return -1; } FIAL_move_value(val, ref.ref, env->interp); break; case AST_INIT_COPY_ID: res = get_ref_from_sym_block_stack(&ref, node->sym, env->block_stack); if (res != 0) { env->error.code = ERROR_UNDECLARED_VAR; env->error.static_msg = "unknown variable in copy assignmnet"; FIAL_set_error(env); return -1; } FIAL_copy_value(val, ref.ref, env->interp); break; case AST_INIT_MOVE_ACS: res = get_ref_from_map_access(&ref, node->left, env->block_stack); if (res != 0) { env->error.code = ERROR_INVALID_MAP_ACCESS; env->error.static_msg = "bad map access in move assignment"; FIAL_set_error(env); return -1; } FIAL_move_value (val, ref.ref, env->interp); break; case AST_INIT_COPY_ACS: res = get_ref_from_map_access(&ref, node->left, env->block_stack); if (res != 0) { env->error.code = ERROR_INVALID_MAP_ACCESS; env->error.static_msg = "bad map access in copy assignment"; FIAL_set_error(env); return -1; } FIAL_copy_value (val, ref.ref, env->interp); break; default: if (eval_expression(val, node, env) < 0) return -1; break; } return 0; }
static int insert_args (node *arglist_to, node *arglist_from, struct FIAL_symbol_map *map_to, block *block_stack, exec_env *env) { node *iter1, *iter2; value val, ref, none; int res; memset(&none, 0, sizeof(val)); iter1 = arglist_to; iter2 = arglist_from->left; for(; iter1 != NULL; iter1=iter1->right) { if(iter2) { res = 0; val = ref = none; switch(iter2->type) { case AST_ARGLIST_ID: res = get_ref_from_sym_block_stack (&ref, iter2->sym, block_stack); if(res == 1) { return -2; } res = set_symbol(map_to, iter1->sym, &ref, env->interp); if(res == -1) { return -1; } break; case AST_ARGLIST_EXPR: assert(iter2->type == AST_ARGLIST_EXPR); if(eval_expression(&val, iter2->left,env) < 0) { return -3; } res = set_symbol(map_to, iter1->sym, &val, env->interp); if (res == -1) return -1; break; case AST_ARGLIST_INIT: if(handle_initializer(&val, iter2->left, env) < 0) { return -4; } res = set_symbol(map_to, iter1->sym, &val, env->interp); if(res == -1) return -1; break; case AST_ARGLIST_MOVE_ID: res = get_ref_from_sym_block_stack(&ref, iter2->sym, block_stack); if(res == 1) { return -2; } val = *ref.ref; res = set_symbol(map_to, iter1->sym, &val, env->interp); if(res == -1) { return -1; } memset(ref.ref, 0, sizeof(*ref.ref)); break; case AST_ARGLIST_COPY_ID: res = get_ref_from_sym_block_stack(&ref, iter2->sym, block_stack); if(res == 1) { return -2; } FIAL_copy_value (&val, ref.ref, env->interp); res = set_symbol(map_to, iter1->sym, &val, env->interp); if(res == -1) { FIAL_clear_value(&val, env->interp); return -1; } break; case AST_ARGLIST_MOVE_ACS: assert(iter2->left); res = get_ref_from_map_access(&ref, iter2->left, env->block_stack); if (res != 0) return -5; res = set_symbol(map_to, iter1->sym, ref.ref, env->interp); if(res < 0) return -1; *ref.ref = none; break; case AST_ARGLIST_COPY_ACS: assert(iter2->left); res = get_ref_from_map_access(&ref, iter2->left, env->block_stack); if(res != 0) return -5; if( FIAL_copy_value(&val, ref.ref, env->interp) < 0) return -1; if(set_symbol(map_to, iter1->sym, &val, env->interp) < 0) { return -1; } break; default: assert(0); } iter2 = iter2->right; } else { int res; assert(!iter2); res = set_symbol(map_to, iter1->sym, &none, env->interp); if(res == -1) { return -1; } } } return 0; }
void handle(node *n) { if (n->type == type_id) { vlog("[code_gen] handle: identifier\n"); handle_identifier(n); } else if (n->type == type_con) { vlog("[code_gen] handle: constant\n"); handle_constant(n); } else if (n->type == type_string) { vlog("[code_gen] handle: string constant\n"); handle_string(n); } else { if (strcmp(n->id,"postfix_expr") == 0) { vlog("[code_gen] handle: postfix_expr \n"); handle_postfix_expr(n); } else if (strcmp(n->id,"argument_expr_list") == 0) { vlog("[code_gen] handle: argument_expr_list \n"); handle_argument_expr_list(n); } else if (strcmp(n->id,"unary_expr") == 0) { vlog("[code_gen] handle: unary_expr \n"); handle_unary_expr(n); } else if (strcmp(n->id,"sizeof") == 0) { vlog("[code_gen] handle: sizeof \n"); handle_sizeof(n); } else if (strcmp(n->id,"cast_expr") == 0) { vlog("[code_gen] handle: cast_expr \n"); handle_cast_expr(n); } else if (strcmp(n->id,"multiply") == 0) { vlog("[code_gen] handle: multiply \n"); handle_multiply(n); } else if (strcmp(n->id,"divide") == 0) { vlog("[code_gen] handle: divide \n"); handle_divide(n); } else if (strcmp(n->id,"mod") == 0) { vlog("[code_gen] handle: mod \n"); handle_mod(n); } else if (strcmp(n->id,"add") == 0) { vlog("[code_gen] handle: add \n"); handle_add(n); } else if (strcmp(n->id,"sub") == 0) { vlog("[code_gen] handle: sub \n"); handle_sub(n); } else if (strcmp(n->id,"shift_left") == 0) { vlog("[code_gen] handle: shift_left \n"); handle_shift_left(n); } else if (strcmp(n->id,"shift_right") == 0) { vlog("[code_gen] handle: shift_right \n"); handle_shift_right(n); } else if (strcmp(n->id,"less_than") == 0) { vlog("[code_gen] handle: less_than \n"); handle_less_than(n); } else if (strcmp(n->id,"greater_than") == 0) { vlog("[code_gen] handle: greater_than \n"); handle_greater_than(n); } else if (strcmp(n->id,"less_equal_than") == 0) { vlog("[code_gen] handle: less_equal_than \n"); handle_less_equal_than(n); } else if (strcmp(n->id,"greater_equal_than") == 0) { vlog("[code_gen] handle: greater_equal_than \n"); handle_greater_equal_than(n); } else if (strcmp(n->id,"equality") == 0) { vlog("[code_gen] handle: equality \n"); handle_equality(n); } else if (strcmp(n->id,"equality_not") == 0) { vlog("[code_gen] handle: equality_not \n"); handle_equality_not(n); } else if (strcmp(n->id,"bitwise_and") == 0) { vlog("[code_gen] handle: bitwise_and \n"); handle_bitwise_and(n); } else if (strcmp(n->id,"bitwise_xor") == 0) { vlog("[code_gen] handle: bitwise_xor \n"); handle_bitwise_xor(n); } else if (strcmp(n->id,"bitwise_or") == 0) { vlog("[code_gen] handle: bitwise_or \n"); handle_bitwise_or(n); } else if (strcmp(n->id,"logical_and") == 0) { vlog("[code_gen] handle: logical_and \n"); handle_logical_and(n); } else if (strcmp(n->id,"logical_or") == 0) { vlog("[code_gen] handle: logical_or \n"); handle_logical_or(n); } else if (strcmp(n->id,"conditional") == 0) { vlog("[code_gen] handle: conditional \n"); handle_conditional(n); } else if (strcmp(n->id,"assignment") == 0) { vlog("[code_gen] handle: assignment \n"); handle_assignment(n); } else if (strcmp(n->id,"expression") == 0) { vlog("[code_gen] handle: expression \n"); handle_expression(n); } else if (strcmp(n->id,"declaration") == 0) { vlog("[code_gen] handle: declaration \n"); handle_declaration(n); } else if (strcmp(n->id,"declaration_specifier") == 0) { vlog("[code_gen] handle: declaration_specifier \n"); handle_declaration_specifier(n); } else if (strcmp(n->id,"init_declarator_list") == 0) { vlog("[code_gen] handle: init_declarator_list \n"); handle_init_declarator_list(n); } else if (strcmp(n->id,"init_declarator") == 0) { vlog("[code_gen] handle: init_declarator \n"); handle_init_declarator(n); } else if (strcmp(n->id,"struct_union") == 0) { vlog("[code_gen] handle: struct_union \n"); handle_struct_union(n); } else if (strcmp(n->id,"struct_declaration_list") == 0) { vlog("[code_gen] handle: struct_declaration_list \n"); handle_struct_declaration_list(n); } else if (strcmp(n->id,"struct_declaration") == 0) { vlog("[code_gen] handle: struct_declaration \n"); handle_struct_declaration(n); } else if (strcmp(n->id,"specifier_qualifier_list") == 0) { vlog("[code_gen] handle: specifier_qualifier_list \n"); handle_specifier_qualifier_list(n); } else if (strcmp(n->id,"struct_declarator_list") == 0) { vlog("[code_gen] handle: struct_declarator_list \n"); handle_struct_declarator_list(n); } else if (strcmp(n->id,"struct_declarator") == 0) { vlog("[code_gen] handle: struct_declarator \n"); handle_struct_declarator(n); } else if (strcmp(n->id,"enum_specifier") == 0) { vlog("[code_gen] handle: enum_specifier \n"); handle_enum_specifier(n); } else if (strcmp(n->id,"enum_list") == 0) { vlog("[code_gen] handle: enum_list \n"); handle_enum_list(n); } else if (strcmp(n->id,"enumerator") == 0) { vlog("[code_gen] handle: enumerator \n"); handle_enumerator(n); } else if (strcmp(n->id,"declarator") == 0) { vlog("[code_gen] handle: declarator \n"); handle_declarator(n); } else if (strcmp(n->id,"direct_declarator") == 0) { vlog("[code_gen] handle: direct_declarator \n"); handle_direct_declarator(n); } else if (strcmp(n->id,"pointer") == 0) { vlog("[code_gen] handle: pointer \n"); handle_pointer(n); } else if (strcmp(n->id,"type_qualifier_list") == 0) { vlog("[code_gen] handle: type_qualifier_list \n"); handle_type_qualifier_list(n); } else if (strcmp(n->id,"parameter_type_list") == 0) { vlog("[code_gen] handle: parameter_type_list \n"); handle_parameter_type_list(n); } else if (strcmp(n->id,"parameter_list") == 0) { vlog("[code_gen] handle: parameter_list \n"); handle_parameter_list(n); } else if (strcmp(n->id,"parameter_declaration") == 0) { vlog("[code_gen] handle: parameter_declaration \n"); handle_parameter_declaration(n); } else if (strcmp(n->id,"identifier_list") == 0) { vlog("[code_gen] handle: identifier_list \n"); handle_identifier_list(n); } else if (strcmp(n->id,"type_name") == 0) { vlog("[code_gen] handle: type_name \n"); handle_type_name(n); } else if (strcmp(n->id,"abstract_declarator") == 0) { vlog("[code_gen] handle: abstract_declarator \n"); handle_abstract_declarator(n); } else if (strcmp(n->id,"direct_abstract_declarator") == 0) { vlog("[code_gen] handle: direct_abstract_declarator \n"); handle_direct_abstract_declarator(n); } else if (strcmp(n->id,"initializer") == 0) { vlog("[code_gen] handle: initializer \n"); handle_initializer(n); } else if (strcmp(n->id,"initializer_list") == 0) { vlog("[code_gen] handle: initializer_list \n"); handle_initializer_list(n); } else if (strcmp(n->id,"labeled_statement") == 0) { vlog("[code_gen] handle: labeled_statement \n"); handle_labeled_statement(n); } else if (strcmp(n->id,"compound_statement") == 0) { vlog("[code_gen] handle: compound_statement \n"); handle_compound_statement(n); } else if (strcmp(n->id,"declaration_list") == 0) { vlog("[code_gen] handle: declaration_list \n"); handle_declaration_list(n); } else if (strcmp(n->id,"statement_list") == 0) { vlog("[code_gen] handle: statement_list \n"); handle_statement_list(n); } else if (strcmp(n->id,"expression_statement") == 0) { vlog("[code_gen] handle: expression_statement \n"); handle_expression_statement(n); } else if (strcmp(n->id,"selection_statement") == 0) { vlog("[code_gen] handle: selection_statement \n"); handle_selection_statement(n); } else if (strcmp(n->id,"iteration_statement") == 0) { vlog("[code_gen] handle: iteration_statement \n"); handle_iteration_statement(n); } else if (strcmp(n->id,"jump_statement") == 0) { vlog("[code_gen] handle: jump_statement \n"); handle_jump_statement(n); } else if (strcmp(n->id,"translation_unit") == 0) { vlog("[code_gen] handle: translation_unit \n"); handle_translation_unit(n); } else if (strcmp(n->id,"function_definition") == 0) { vlog("[code_gen] handle: function_definition \n"); handle_function_definition(n); } else if (strcmp(n->id,"asm") == 0) { vlog("[code_gen] handle: inline_assembly \n"); handle_asm(n); } } }