aboutsummaryrefslogtreecommitdiff
path: root/gcc/treelang/treetree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/treelang/treetree.c')
-rw-r--r--gcc/treelang/treetree.c146
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;