# HG changeset patch # User mir3636 # Date 1510914343 -32400 # Node ID e234ee7b7292e9b8182b480420ef828549ff2740 # Parent bdf41c9fa0b7421eb35d6d7c5a3cde2801bebfb3 fix c-parser.c diff -r bdf41c9fa0b7 -r e234ee7b7292 gcc/c/c-parser.c --- a/gcc/c/c-parser.c Fri Nov 17 06:33:55 2017 +0900 +++ b/gcc/c/c-parser.c Fri Nov 17 19:25:43 2017 +0900 @@ -2771,7 +2771,7 @@ if(!TARGET_64BIT) { attrs = build_tree_list (get_identifier("fastcall"), NULL_TREE); - declspecs_add_attrs(specs, attrs); + declspecs_add_attrs(loc, specs, attrs); } c_parser_consume_token (parser); @@ -5497,10 +5497,49 @@ which is not enclosed in braces and has an else clause. This is used to implement -Wparentheses. */ +static tree +cbc_replace_arguments (location_t loc, tree call) +{ + tree arg; + tree fn; + tree tmp_decl; + int i=0; + call_expr_arg_iterator iter; + + fn = CALL_EXPR_FN (call); + if ( TREE_CODE (fn)==PARM_DECL || !TREE_CONSTANT (fn) ) + { + tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(fn)); + pushdecl (tmp_decl); + + add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, fn, NULL_TREE)); + CALL_EXPR_FN (call) = tmp_decl; + } + + FOR_EACH_CALL_EXPR_ARG (arg, iter, call) + { + /* if ( !CONSTANT_CLASS_P (arg) && !VAR_OR_FUNCTION_DECL_P (arg) ) */ + if ( TREE_CODE (arg)==PARM_DECL || !TREE_CONSTANT (arg) ) + { + tmp_decl = build_decl (loc, VAR_DECL, NULL_TREE, TREE_TYPE(arg)); + pushdecl (tmp_decl); + + add_stmt (build_modify_expr (loc, tmp_decl, NULL_TREE, NOP_EXPR, loc, arg, NULL_TREE)); + CALL_EXPR_ARG (call, i) = tmp_decl; + } + i++; + } + + return call; +} + static void c_parser_statement_after_labels (c_parser *parser, bool *if_p, vec *chain) { +#ifndef noCbC + struct c_expr expr; +#endif location_t loc = c_parser_peek_token (parser)->location; tree stmt = NULL_TREE; bool in_if_block = parser->in_if_block; @@ -7951,6 +7990,146 @@ Classname . identifier */ +static void +cbc_finish_labeled_goto (location_t loc, tree label, tree retval) +{ + /* add statement below. + * + * if (0) { + * _cbc_exit0: + * return retval; + * } + */ + tree tlab; + tree cond; + + cond = integer_zero_node; + tree block_outside = c_begin_compound_stmt (false); + tree block_inside = c_begin_compound_stmt (false); + + tree stmt = c_begin_compound_stmt (true); + tlab = define_label (loc, label); + gcc_assert (tlab); + decl_attributes (&tlab, NULL_TREE, 0); + TREE_USED (tlab) = 1; + /* add_stmt (LABEL_EXPR) */ + add_stmt (build_stmt (loc, LABEL_EXPR, tlab)); + + /* add_stmt (RETURN_EXPR) */ + tree ret = c_finish_return (loc, retval, retval); + DECL_READ_P(retval) = 1; // (NODE)->decl_common.decl_read_flag = 1; + // TREE_USED(ret) = 1; + tree stmt_body = c_end_compound_stmt (loc, stmt, true); + + /* add_stmt (STATEMENT_LIST) : STATEMENT_LIST -> LABEL_EXPR -> RETURN_EXPR */ + add_stmt (stmt_body); + + tree body = c_end_compound_stmt (loc, block_inside, false); + + /* add_stmt (COND_EXPR) */ + c_finish_if_stmt (loc, cond, body, NULL_TREE); + + /* add_stmt (BIND_EXPR) : BIND_EXPR -> COND_EXPR -> STATEMENT_LIST */ + tree bind = c_end_compound_stmt (loc, block_outside, false); + TREE_SIDE_EFFECTS (bind) = 1; + add_stmt (bind); + + TREE_USED (retval) = 1; + +} +static tree +cbc_finish_nested_function (location_t loc, tree label, tree retval_decl) +{ + + /* add statement below. + * void ___cbc_internal_return(int _retval, void *_envp){ + * retval = _retval; + * goto exit0; + * } + */ + /* TODO: + * retval(lhs)のTREE_DECLを引数から取得するように + * int _retvalパラメータのタイプはretvalに合わせる + */ + + tree fnbody; + tree _retval_decl, _envp_decl; + struct c_declarator *declarator; + //tree ident; + struct c_arg_info *args; + struct c_declspecs *specs; + struct c_typespec t; + { + tree expr; + push_scope (); + declare_parm_level (); + /*tree retval_type = TREE_TYPE(retval_decl);*/ + + _retval_decl = build_decl (loc, PARM_DECL, get_identifier ("_retval"), TREE_TYPE(retval_decl)); + DECL_SOURCE_LOCATION (_retval_decl) = loc; + DECL_ARTIFICIAL (_retval_decl) = 1; + DECL_ARG_TYPE (_retval_decl) = TREE_TYPE(retval_decl); + pushdecl (_retval_decl); + finish_decl (_retval_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); + _envp_decl = build_decl (loc, PARM_DECL, get_identifier ("_envp"), ptr_type_node); + DECL_SOURCE_LOCATION (_envp_decl) = loc; + DECL_ARTIFICIAL (_envp_decl) = 1; + DECL_ARG_TYPE (_envp_decl) = ptr_type_node; + pushdecl (_envp_decl); + finish_decl (_envp_decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); + struct c_declarator declarator; + struct c_parm* parm; + struct c_declspecs *specs_parm = build_null_declspecs(); + declspecs_add_type (loc, specs_parm, TREE_TYPE(retval_decl)); + finish_declspecs (specs_parm); + parm = build_c_parm (specs_parm, NULL_TREE, + &declarator, loc); + + args = get_parm_info(false, expr); + pop_scope(); + } + + t.kind = ctsk_resword; + t.spec = get_identifier("void"); + specs = build_null_declspecs(); + declspecs_add_type (loc, specs, t); + finish_declspecs (specs); + + /* make nested function. */ + declarator = build_id_declarator (get_identifier ("_cbc_internal_return")); + 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); + + add_stmt (build_modify_expr (loc, retval_decl, NULL_TREE, NOP_EXPR, loc, _retval_decl, NULL_TREE)); + tree stmt = c_finish_goto_label (loc, label); + + /* end compound statement. */ + fnbody = c_end_compound_stmt (loc, 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 (loc, DECL_EXPR, decl)); + return decl; + +} + static struct c_expr c_parser_postfix_expression (c_parser *parser) { @@ -8626,7 +8805,8 @@ TREE_USED (decl_cond) = 1; /* Use thread-local */ - DECL_TLS_MODEL (decl_cond) = decl_default_tls_model (decl_cond); + //DECL_TLS_MODEL (decl_cond) = decl_default_tls_model (decl_cond); + set_decl_tls_model (decl_cond, decl_default_tls_model (decl_cond)); DECL_NONLOCAL (decl_cond) = 1; DECL_ARTIFICIAL (decl_cond) = 1; add_stmt (build_stmt(location, DECL_EXPR, pushdecl (decl_cond))); @@ -8641,7 +8821,8 @@ cbc_finish_labeled_goto (location, label, decl_cond); /* get pointer to nested function. */ - value = build_addr (decl , current_function_decl); + //value = build_addr (decl , current_function_decl); + value = build_addr (decl); TREE_USED (current_function_decl) = 1; SET_EXPR_LOCATION (value, location); add_stmt (value); diff -r bdf41c9fa0b7 -r e234ee7b7292 gcc/tree.h --- a/gcc/tree.h Fri Nov 17 06:33:55 2017 +0900 +++ b/gcc/tree.h Fri Nov 17 19:25:43 2017 +0900 @@ -4740,6 +4740,10 @@ extern location_t tree_nonartificial_location (tree); extern tree block_ultimate_origin (const_tree); extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree); +#ifndef noCbC +extern tree build_addr (tree); +#endif + extern bool virtual_method_call_p (const_tree); extern tree obj_type_ref_class (const_tree ref); extern bool types_same_for_odr (const_tree type1, const_tree type2,