diff options
Diffstat (limited to 'gcc/treelang/treetree.c')
-rw-r--r-- | gcc/treelang/treetree.c | 146 |
1 files changed, 70 insertions, 76 deletions
diff --git a/gcc/treelang/treetree.c b/gcc/treelang/treetree.c index b621fadf183..aea6e0ba5cb 100644 --- a/gcc/treelang/treetree.c +++ b/gcc/treelang/treetree.c @@ -5,7 +5,7 @@ you are in the right place. Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This code is based on toy.c written by Richard Kenner. @@ -325,6 +325,7 @@ tree_code_create_function_prototype (unsigned char* chars, tree type_node; tree fn_type; tree fn_decl; + tree parm_list = NULL_TREE; /* Build the type. */ id = get_identifier ((const char*)chars); @@ -351,25 +352,19 @@ tree_code_create_function_prototype (unsigned char* chars, DECL_CONTEXT (fn_decl) = NULL_TREE; DECL_SOURCE_LOCATION (fn_decl) = loc; - TREE_USED (fn_decl) = 1; - TREE_PUBLIC (fn_decl) = 0; DECL_EXTERNAL (fn_decl) = 0; TREE_STATIC (fn_decl) = 0; switch (storage_class) { case STATIC_STORAGE: - TREE_PUBLIC (fn_decl) = 0; break; case EXTERNAL_DEFINITION_STORAGE: TREE_PUBLIC (fn_decl) = 1; - TREE_STATIC (fn_decl) = 0; - DECL_EXTERNAL (fn_decl) = 0; break; case EXTERNAL_REFERENCE_STORAGE: - TREE_PUBLIC (fn_decl) = 0; DECL_EXTERNAL (fn_decl) = 1; break; @@ -378,6 +373,37 @@ tree_code_create_function_prototype (unsigned char* chars, gcc_unreachable (); } + /* Make the argument variable decls. */ + for (parm = parms; parm; parm = parm->tp.par.next) + { + tree parm_decl = build_decl (PARM_DECL, get_identifier + ((const char*) (parm->tp.par.variable_name)), + tree_code_get_type (parm->type)); + + /* Some languages have different nominal and real types. */ + DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl); + gcc_assert (DECL_ARG_TYPE (parm_decl)); + gcc_assert (fn_decl); + DECL_CONTEXT (parm_decl) = fn_decl; + DECL_SOURCE_LOCATION (parm_decl) = loc; + parm_list = chainon (parm_decl, parm_list); + } + + /* Back into reverse order as the back end likes them. */ + parm_list = nreverse (parm_list); + + DECL_ARGUMENTS (fn_decl) = parm_list; + + /* Save the decls for use when the args are referred to. */ + for (parm = parms; parm_list; + parm_list = TREE_CHAIN (parm_list), + parm = parm->tp.par.next) + { + gcc_assert (parm); /* Too few. */ + *parm->tp.par.where_to_put_var_tree = parm_list; + } + gcc_assert (!parm); /* Too many. */ + /* Process declaration of function defined elsewhere. */ rest_of_decl_compilation (fn_decl, 1, 0); @@ -386,21 +412,16 @@ tree_code_create_function_prototype (unsigned char* chars, /* Output code for start of function; the decl of the function is in - PREV_SAVED (as created by tree_code_create_function_prototype), - the function is at line number LINENO in file FILENAME. The - parameter details are in the lists PARMS. Returns nothing. */ + PREV_SAVED (as created by tree_code_create_function_prototype), + the function is at line number LINENO in file FILENAME. The + parameter details are in the lists PARMS. Returns nothing. */ + void tree_code_create_function_initial (tree prev_saved, - location_t loc, - struct prod_token_parm_item* parms) + location_t loc) { tree fn_decl; - tree param_decl; - tree parm_decl; - tree parm_list; tree resultdecl; - struct prod_token_parm_item* this_parm; - struct prod_token_parm_item* parm; fn_decl = prev_saved; gcc_assert (fn_decl); @@ -426,49 +447,11 @@ tree_code_create_function_initial (tree prev_saved, DECL_SOURCE_LOCATION (resultdecl) = loc; DECL_RESULT (fn_decl) = resultdecl; - /* Make the argument variable decls. */ - parm_list = NULL_TREE; - for (parm = parms; parm; parm = parm->tp.par.next) - { - parm_decl = build_decl (PARM_DECL, get_identifier - ((const char*) (parm->tp.par.variable_name)), - tree_code_get_type (parm->type)); - - /* Some languages have different nominal and real types. */ - DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl); - gcc_assert (DECL_ARG_TYPE (parm_decl)); - gcc_assert (fn_decl); - DECL_CONTEXT (parm_decl) = fn_decl; - DECL_SOURCE_LOCATION (parm_decl) = loc; - parm_list = chainon (parm_decl, parm_list); - } - - /* Back into reverse order as the back end likes them. */ - parm_list = nreverse (parm_list); - - DECL_ARGUMENTS (fn_decl) = parm_list; - - /* Save the decls for use when the args are referred to. */ - for (param_decl = DECL_ARGUMENTS (fn_decl), - this_parm = parms; - param_decl; - param_decl = TREE_CHAIN (param_decl), - this_parm = this_parm->tp.par.next) - { - gcc_assert (this_parm); /* Too few. */ - *this_parm->tp.par.where_to_put_var_tree = param_decl; - } - gcc_assert (!this_parm); /* Too many. */ - /* Create a new level at the start of the function. */ pushlevel (0); - /* Force it to be output, else may be solely inlined. */ - TREE_ADDRESSABLE (fn_decl) = 1; - - /* Stop -O3 from deleting it. */ - TREE_USED (fn_decl) = 1; + TREE_STATIC (fn_decl) = 1; } /* Wrapup a function contained in file FILENAME, ending at line LINENO. */ @@ -552,41 +535,31 @@ tree_code_create_variable (unsigned int storage_class, DECL_SOURCE_LOCATION (var_decl) = loc; + DECL_EXTERNAL (var_decl) = 0; + TREE_PUBLIC (var_decl) = 0; + TREE_STATIC (var_decl) = 0; /* Set the storage mode and whether only visible in the same file. */ switch (storage_class) { case STATIC_STORAGE: TREE_STATIC (var_decl) = 1; - TREE_PUBLIC (var_decl) = 0; break; case AUTOMATIC_STORAGE: - TREE_STATIC (var_decl) = 0; - TREE_PUBLIC (var_decl) = 0; break; case EXTERNAL_DEFINITION_STORAGE: - TREE_STATIC (var_decl) = 0; TREE_PUBLIC (var_decl) = 1; break; case EXTERNAL_REFERENCE_STORAGE: DECL_EXTERNAL (var_decl) = 1; - TREE_PUBLIC (var_decl) = 0; break; default: gcc_unreachable (); } - /* This should really only be set if the variable is used. */ - TREE_USED (var_decl) = 1; - - /* Expand declaration and initial value if any. */ - - if (TREE_STATIC (var_decl)) - rest_of_decl_compilation (var_decl, 0, 0); - TYPE_NAME (TREE_TYPE (var_decl)) = TYPE_NAME (var_type); return pushdecl (copy_node (var_decl)); } @@ -616,6 +589,9 @@ tree_code_generate_return (tree type, tree exp) TREE_SIDE_EFFECTS (setret) = 1; TREE_USED (setret) = 1; setret = build1 (RETURN_EXPR, type, setret); + /* Use EXPR_LOCUS so we don't lose any information about the file we + are compiling. */ + SET_EXPR_LOCUS (setret, EXPR_LOCUS (exp)); } else setret = build1 (RETURN_EXPR, type, NULL_TREE); @@ -664,7 +640,8 @@ tree_code_get_integer_value (unsigned char* chars, unsigned int length) for (ix = start; ix < length; ix++) val = val * 10 + chars[ix] - (unsigned char)'0'; val = val*negative; - return build_int_cst_wide (NULL_TREE, + return build_int_cst_wide (start == 1 ? + integer_type_node : unsigned_type_node, val & 0xffffffff, (val >> 32) & 0xffffffff); } @@ -673,7 +650,8 @@ tree_code_get_integer_value (unsigned char* chars, unsigned int length) tree tree_code_get_expression (unsigned int exp_type, tree type, tree op1, tree op2, - tree op3 ATTRIBUTE_UNUSED) + tree op3 ATTRIBUTE_UNUSED, + location_t loc) { tree ret1; int operator; @@ -711,19 +689,22 @@ tree_code_get_expression (unsigned int exp_type, /* Reference to a variable. This is dead easy, just return the decl for the variable. If the TYPE is different than the - variable type, convert it. */ + variable type, convert it. However, to keep accurate location + information we wrap it in a NOP_EXPR is is easily stripped. */ case EXP_REFERENCE: gcc_assert (op1); + TREE_USED (op1) = 1; if (type == TREE_TYPE (op1)) - ret1 = op1; + ret1 = build1 (NOP_EXPR, type, op1); else ret1 = fold (build1 (CONVERT_EXPR, type, op1)); break; case EXP_FUNCTION_INVOCATION: - gcc_assert (op1 && op2); + gcc_assert (op1); { tree fun_ptr; + TREE_USED (op1) = 1; fun_ptr = fold (build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (op1)), op1)); ret1 = build3 (CALL_EXPR, type, fun_ptr, nreverse (op2), NULL_TREE); @@ -734,6 +715,10 @@ tree_code_get_expression (unsigned int exp_type, gcc_unreachable (); } + /* Declarations already have a location and constants can be shared so they + shouldn't a location set on them. */ + if (! DECL_P (ret1) && ! TREE_CONSTANT (ret1)) + SET_EXPR_LOCATION (ret1, loc); return ret1; } @@ -893,7 +878,10 @@ tree_lang_type_for_size (unsigned precision, int unsignedp) static tree tree_lang_type_for_mode (enum machine_mode mode, int unsignedp) { - return tree_lang_type_for_size (GET_MODE_BITSIZE (mode), unsignedp); + if (SCALAR_INT_MODE_P (mode)) + return tree_lang_type_for_size (GET_MODE_BITSIZE (mode), unsignedp); + else + return NULL_TREE; } /* Return the unsigned version of a TYPE_NODE, a scalar type. */ @@ -1131,6 +1119,12 @@ pushdecl (tree decl) && TYPE_NAME (TREE_TYPE (decl)) == 0) TYPE_NAME (TREE_TYPE (decl)) = DECL_NAME (decl); + /* Put automatic variables into the intermediate representation. */ + if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl) + && !TREE_STATIC (decl) && !TREE_PUBLIC (decl)) + tree_code_output_expression_statement (build1 (DECL_EXPR, void_type_node, + decl), + DECL_SOURCE_LOCATION (decl)); return decl; } @@ -1209,7 +1203,7 @@ treelang_init_decl_processing (void) tree_push_type_decl (get_identifier ("long double"), long_double_type_node); tree_push_type_decl (get_identifier ("void"), void_type_node); - /* Add any target-specific builtin functions. */ + build_common_builtin_nodes (); (*targetm.init_builtins) (); pedantic_lvalues = pedantic; |