# HG changeset patch # User kent # Date 1252411467 -32400 # Node ID 26e357f6275f55c82b5d0cdf2c1f927c9519968e # Parent ddf292032e7d763a87fe0612f9795aeb5c259ff2 add cbc_make_nested_function diff -r ddf292032e7d -r 26e357f6275f gcc/c-parser.c --- a/gcc/c-parser.c Wed Aug 26 15:11:42 2009 +0900 +++ b/gcc/c-parser.c Tue Sep 08 21:04:27 2009 +0900 @@ -59,6 +59,7 @@ #include "cgraph.h" #ifndef noCbC #include "cbc-tree.h" +static tree cbc_make_nested_function (location_t); #endif @@ -3795,8 +3796,11 @@ tree env = NULL_TREE; // if (c_parser_next_token_is (parser, CPP_COMMA)) // env = c_parser_cbc_make_env(parser); - CbC_IS_CbC_GOTO (expr.value) = 1; - CALL_EXPR_TAILCALL (expr.value) = 1; + if (CbC_IS_CODE_SEGMENT(TREE_TYPE(current_function_decl))) + { + CbC_IS_CbC_GOTO (expr.value) = 1; + CALL_EXPR_TAILCALL (expr.value) = 1; + } add_stmt(expr.value); CbC_HAVE_CbC_GOTO (current_function_decl) = 1; // should be match with function type? @@ -5603,7 +5607,9 @@ case RID_CbC_RET: case RID_RETURN: - if (cbc_return_f==0) { tree retval; +#if 0 + if (cbc_return_f==0) + { tree retval; /* Generates something like... @@ -5694,15 +5700,40 @@ expr.value = c_finish_stmt_expr (stmt); expr.original_code = ERROR_MARK; - } else { + + } + else + { //tree label = lookup_label(c_parser_peek_token (parser)->value); //TREE_USED(label) = 1; //expr.value = build1(ADDR_EXPR, ptr_type_node, label); expr.value = build1(ADDR_EXPR, ptr_type_node, return_label1); c_parser_consume_token (parser); - } - break; -#endif + } +#else //by KENT. + { + c_parser_consume_token (parser); + + tree stmt = c_begin_stmt_expr (); + cbc_return_f = c_parser_peek_token (parser)->value; + location_t location = c_parser_peek_token (parser)->location; + + //add_stmt (cbc_make_nested_function (location)); + tree nested_func = cbc_make_nested_function (location); + add_stmt (build_stmt (DECL_EXPR, nested_func)); + + tree value = build_addr (nested_func , current_function_decl); + SET_EXPR_LOCATION (value, location); + add_stmt (value); + + TREE_SIDE_EFFECTS (stmt) = 1; + expr.value = c_finish_stmt_expr (stmt); + expr.original_code = ERROR_MARK; + } + +#endif //0 + break; +#endif //noCbC default: c_parser_error (parser, "expected expression"); expr.value = error_mark_node; @@ -5734,6 +5765,109 @@ return c_parser_postfix_expression_after_primary (parser, expr); } +static tree +cbc_make_nested_function (location_t loc) +{ + + /* + * void __return_func(int _retval, void *fp){ + * retval = _retval; + * goto exit0; + * } + */ + + tree fnbody; + struct c_declarator *declarator; + tree ident; + struct c_arg_info *args; + struct c_declspecs *specs; + struct c_typespec t; + + { /* nested function's parameters (int _retval,void *fp) */ + struct c_declspecs *_retval_specs, + *_envp_specs; + struct c_declarator*_retval_decl, + *_envp_decl; + struct c_parm *_retval, + *_envp; + tree _retval_ident, + _envp_ident; + struct c_typespec t; + + push_scope (); + declare_parm_level (); + + _retval_specs = build_null_declspecs(); + t.kind = ctsk_resword; + //t.spec = integer_type_node; + t.spec = get_identifier("int"); + declspecs_add_type (_retval_specs, t); + finish_declspecs (_retval_specs); + _retval_decl = build_id_declarator (get_identifier ("_retval")); + _retval = build_c_parm (_retval_specs, NULL_TREE, _retval_decl); + + push_parm_decl(_retval); + + _envp_specs = build_null_declspecs(); + t.kind = ctsk_resword; + t.spec = get_identifier("void"); + declspecs_add_type (_envp_specs, t); + finish_declspecs (_envp_specs); + _envp_decl = build_id_declarator (get_identifier ("_envp")); + _envp_decl = make_pointer_declarator (build_null_declspecs (), _envp_decl); + _envp = build_c_parm (_envp_specs, NULL_TREE, _envp_decl); + + push_parm_decl(_envp); + + args = get_parm_info(false); + pop_scope(); + } + + t.kind = ctsk_resword; + t.spec = get_identifier("void"); + specs = build_null_declspecs(); + declspecs_add_type (specs, t); + finish_declspecs (specs); + + /* make nested function. */ + //ident = build_decl (/*TODO:*/VAR_DECL, get_identifier ("_cbc_internal_return"), specs->type); + declarator = build_id_declarator (get_identifier ("_cbc_internal_return")); + //declarator->id_loc = ; + declarator = build_function_declarator (args, declarator); + + c_push_function_context (); + + if (!start_function (specs, declarator, NULL_TREE)) + { + c_pop_function_context(); + gcc_assert (0); + } + store_parm_decls (); + + + /* start compound statement. */ + tree cstmt = c_begin_compound_stmt (true); + + tree lhs = build_external_ref (get_identifier("retval"), false, loc); + tree rhs = build_external_ref (get_identifier("_retval"), false, loc); + add_stmt (build_modify_expr (loc, lhs, NOP_EXPR, rhs)); + tree stmt = c_finish_goto_label (get_identifier ("_cbc_exit0")); + + /* end compound statement. */ + fnbody = c_end_compound_stmt (cstmt, true); + TREE_SIDE_EFFECTS (cstmt) = 1; + + /* finish declaration of nested function. */ + tree decl = current_function_decl; + add_stmt (fnbody); + finish_function (); + c_pop_function_context (); + + //add_stmt (build_stmt (DECL_EXPR, decl)); + //return build_stmt (DECL_EXPR, decl); + return decl; +} + /* Parse a postfix expression after a parenthesized type name: the brace-enclosed initializer of a compound literal, possibly followed by some postfix operators. This is separate because it is not