diff options
Diffstat (limited to 'contrib/gcc/tree.c')
-rw-r--r-- | contrib/gcc/tree.c | 277 |
1 files changed, 157 insertions, 120 deletions
diff --git a/contrib/gcc/tree.c b/contrib/gcc/tree.c index ebe6e14..5e29d2f 100644 --- a/contrib/gcc/tree.c +++ b/contrib/gcc/tree.c @@ -1,5 +1,5 @@ /* Language-independent node constructors for parse phase of GNU compiler. - Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -34,13 +34,7 @@ Boston, MA 02111-1307, USA. */ by all passes of the compiler. */ #include "config.h" -#ifdef __STDC__ -#include <stdarg.h> -#else -#include <varargs.h> -#endif #include "system.h" -#include <setjmp.h> #include "flags.h" #include "tree.h" #include "except.h" @@ -230,7 +224,7 @@ int tree_node_counts[(int)all_kinds]; int tree_node_sizes[(int)all_kinds]; int id_string_size = 0; -char *tree_node_kind_names[] = { +const char *tree_node_kind_names[] = { "decls", "types", "blocks", @@ -269,7 +263,9 @@ int (*lang_get_alias_set) PROTO((tree)); codes are made. */ #define TYPE_HASH(TYPE) ((unsigned long) (TYPE) & 0777777) +static void set_type_quals PROTO((tree, int)); static void append_random_chars PROTO((char *)); +static void build_real_from_int_cst_1 PROTO((PTR)); extern char *mode_name[]; @@ -324,8 +320,11 @@ gcc_obstack_init (obstack) (void (*) ()) OBSTACK_CHUNK_FREE); } -/* Save all variables describing the current status into the structure *P. - This is used before starting a nested function. +/* Save all variables describing the current status into the structure + *P. This function is called whenever we start compiling one + function in the midst of compiling another. For example, when + compiling a nested function, or, in C++, a template instantiation + that is required by the function we are currently compiling. CONTEXT is the decl_function_context for the function we're about to compile; if it isn't current_function_decl, we have to play some games. */ @@ -349,7 +348,7 @@ save_tree_status (p, context) p->rtl_obstack = rtl_obstack; p->inline_obstacks = inline_obstacks; - if (context == current_function_decl) + if (current_function_decl && context == current_function_decl) /* Objects that need to be saved in this function can be in the nonsaved obstack of the enclosing function since they can't possibly be needed once it has returned. */ @@ -747,10 +746,10 @@ void print_obstack_name (object, file, prefix) char *object; FILE *file; - char *prefix; + const char *prefix; { struct obstack *obstack = NULL; - char *obstack_name = NULL; + const char *obstack_name = NULL; struct function *p; for (p = outer_function_chain; p; p = p->next) @@ -944,7 +943,6 @@ make_node (code) register int type = TREE_CODE_CLASS (code); register int length = 0; register struct obstack *obstack = current_obstack; - register int i; #ifdef GATHER_STATISTICS register tree_node_kind kind; #endif @@ -1075,19 +1073,13 @@ make_node (code) } t = (tree) obstack_alloc (obstack, length); + bzero ((PTR) t, length); #ifdef GATHER_STATISTICS tree_node_counts[(int)kind]++; tree_node_sizes[(int)kind] += length; #endif - /* Clear a word at a time. */ - for (i = (length / sizeof (int)) - 1; i >= 0; i--) - ((int *) t)[i] = 0; - /* Clear any extra bytes. */ - for (i = length / sizeof (int) * sizeof (int); i < length; i++) - ((char *) t)[i] = 0; - TREE_SET_CODE (t, code); if (obstack == &permanent_obstack) TREE_PERMANENT (t) = 1; @@ -1107,6 +1099,9 @@ make_node (code) DECL_SOURCE_LINE (t) = lineno; DECL_SOURCE_FILE (t) = (input_filename) ? input_filename : "<built-in>"; DECL_UID (t) = next_decl_uid++; + /* Note that we have not yet computed the alias set for this + declaration. */ + DECL_POINTER_ALIAS_SET (t) = -1; break; case 't': @@ -1141,7 +1136,6 @@ copy_node (node) register tree t; register enum tree_code code = TREE_CODE (node); register int length = 0; - register int i; switch (TREE_CODE_CLASS (code)) { @@ -1190,12 +1184,7 @@ copy_node (node) } t = (tree) obstack_alloc (current_obstack, length); - - for (i = (length / sizeof (int)) - 1; i >= 0; i--) - ((int *) t)[i] = ((int *) node)[i]; - /* Clear any extra bytes. */ - for (i = length / sizeof (int) * sizeof (int); i < length; i++) - ((char *) t)[i] = ((char *) node)[i]; + memcpy (t, node, length); /* EXPR_WITH_FILE_LOCATION must keep filename info stored in TREE_CHAIN */ if (TREE_CODE (node) != EXPR_WITH_FILE_LOCATION) @@ -1255,7 +1244,7 @@ copy_list (list) tree get_identifier (text) - register char *text; + register const char *text; { register int hi; register int i; @@ -1263,11 +1252,11 @@ get_identifier (text) register int len, hash_len; /* Compute length of text in len. */ - for (len = 0; text[len]; len++); + len = strlen (text); /* Decide how much of that length to hash on */ hash_len = len; - if (warn_id_clash && len > id_clash_len) + if (warn_id_clash && (unsigned)len > id_clash_len) hash_len = id_clash_len; /* Compute hash code */ @@ -1286,7 +1275,7 @@ get_identifier (text) return idp; /* <-- return if found */ /* Not found; optionally warn about a similar identifier */ - if (warn_id_clash && do_identifier_warnings && len >= id_clash_len) + if (warn_id_clash && do_identifier_warnings && (unsigned)len >= id_clash_len) for (idp = hash_table[hi]; idp; idp = TREE_CHAIN (idp)) if (!strncmp (IDENTIFIER_POINTER (idp), text, id_clash_len)) { @@ -1318,7 +1307,7 @@ get_identifier (text) tree maybe_get_identifier (text) - register char *text; + register const char *text; { register int hi; register int i; @@ -1326,11 +1315,11 @@ maybe_get_identifier (text) register int len, hash_len; /* Compute length of text in len. */ - for (len = 0; text[len]; len++); + len = strlen (text); /* Decide how much of that length to hash on */ hash_len = len; - if (warn_id_clash && len > id_clash_len) + if (warn_id_clash && (unsigned)len > id_clash_len) hash_len = id_clash_len; /* Compute hash code */ @@ -1461,6 +1450,29 @@ real_value_from_int_cst (type, i) return d; } +struct brfic_args +{ + /* Input */ + tree type, i; + /* Output */ + REAL_VALUE_TYPE d; +}; + +static void +build_real_from_int_cst_1 (data) + PTR data; +{ + struct brfic_args * args = (struct brfic_args *) data; + +#ifdef REAL_ARITHMETIC + args->d = real_value_from_int_cst (args->type, args->i); +#else + args->d = + REAL_VALUE_TRUNCATE (TYPE_MODE (args->type), + real_value_from_int_cst (args->type, args->i)); +#endif +} + /* This function can't be implemented if we can't do arithmetic on the float representation. */ @@ -1472,32 +1484,29 @@ build_real_from_int_cst (type, i) tree v; int overflow = TREE_OVERFLOW (i); REAL_VALUE_TYPE d; - jmp_buf float_error; + struct brfic_args args; v = make_node (REAL_CST); TREE_TYPE (v) = type; - if (setjmp (float_error)) + /* Setup input for build_real_from_int_cst_1() */ + args.type = type; + args.i = i; + + if (do_float_handler (build_real_from_int_cst_1, (PTR) &args)) { + /* Receive output from build_real_from_int_cst_1() */ + d = args.d; + } + else + { + /* We got an exception from build_real_from_int_cst_1() */ d = dconst0; overflow = 1; - goto got_it; } - - set_float_handler (float_error); - -#ifdef REAL_ARITHMETIC - d = real_value_from_int_cst (type, i); -#else - d = REAL_VALUE_TRUNCATE (TYPE_MODE (type), - real_value_from_int_cst (type, i)); -#endif - + /* Check for valid float value for this type on this target machine. */ - got_it: - set_float_handler (NULL_PTR); - #ifdef CHECK_FLOAT_VALUE CHECK_FLOAT_VALUE (TYPE_MODE (type), d, overflow); #endif @@ -1516,7 +1525,7 @@ build_real_from_int_cst (type, i) tree build_string (len, str) int len; - char *str; + const char *str; { /* Put the string in saveable_obstack since it will be placed in the RTL for an "asm" statement and will also be kept around a while if @@ -1558,7 +1567,6 @@ make_tree_vec (len) register tree t; register int length = (len-1) * sizeof (tree) + sizeof (struct tree_vec); register struct obstack *obstack = current_obstack; - register int i; #ifdef GATHER_STATISTICS tree_node_counts[(int)vec_kind]++; @@ -1566,9 +1574,7 @@ make_tree_vec (len) #endif t = (tree) obstack_alloc (obstack, length); - - for (i = (length / sizeof (int)) - 1; i >= 0; i--) - ((int *) t)[i] = 0; + bzero ((PTR) t, length); TREE_SET_CODE (t, TREE_VEC); TREE_VEC_LENGTH (t) = len; @@ -1950,9 +1956,11 @@ chainon (op1, op2) for (t1 = op1; TREE_CHAIN (t1); t1 = TREE_CHAIN (t1)) ; TREE_CHAIN (t1) = op2; +#ifdef ENABLE_CHECKING for (t2 = op2; t2; t2 = TREE_CHAIN (t2)) if (t2 == t1) abort (); /* Circularity created. */ +#endif return op1; } else return op2; @@ -2401,6 +2409,7 @@ first_rtl_op (code) { case SAVE_EXPR: return 2; + case GOTO_SUBROUTINE_EXPR: case RTL_EXPR: return 0; case CALL_EXPR: @@ -2594,6 +2603,7 @@ has_cleanups (exp) switch (TREE_CODE (exp)) { case TARGET_EXPR: + case GOTO_SUBROUTINE_EXPR: case WITH_CLEANUP_EXPR: return 1; @@ -2984,7 +2994,7 @@ stabilize_reference_1 (e) tree build VPROTO((enum tree_code code, tree tt, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES enum tree_code code; tree tt; #endif @@ -2995,7 +3005,7 @@ build VPROTO((enum tree_code code, tree tt, ...)) VA_START (p, tt); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES code = va_arg (p, enum tree_code); tt = va_arg (p, tree); #endif @@ -3059,7 +3069,7 @@ build1 (code, type, node) tree node; { register struct obstack *obstack = expression_obstack; - register int i, length; + register int length; #ifdef GATHER_STATISTICS register tree_node_kind kind; #endif @@ -3075,15 +3085,13 @@ build1 (code, type, node) length = sizeof (struct tree_exp); t = (tree) obstack_alloc (obstack, length); + bzero ((PTR) t, length); #ifdef GATHER_STATISTICS tree_node_counts[(int)kind]++; tree_node_sizes[(int)kind] += length; #endif - for (i = (length / sizeof (int)) - 1; i >= 0; i--) - ((int *) t)[i] = 0; - TREE_TYPE (t) = type; TREE_SET_CODE (t, code); @@ -3110,7 +3118,7 @@ build1 (code, type, node) tree build_nt VPROTO((enum tree_code code, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES enum tree_code code; #endif va_list p; @@ -3120,7 +3128,7 @@ build_nt VPROTO((enum tree_code code, ...)) VA_START (p, code); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES code = va_arg (p, enum tree_code); #endif @@ -3140,7 +3148,7 @@ build_nt VPROTO((enum tree_code code, ...)) tree build_parse_node VPROTO((enum tree_code code, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES enum tree_code code; #endif register struct obstack *ambient_obstack = expression_obstack; @@ -3151,7 +3159,7 @@ build_parse_node VPROTO((enum tree_code code, ...)) VA_START (p, code); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES code = va_arg (p, enum tree_code); #endif @@ -3239,10 +3247,10 @@ build_block (vars, tags, subblocks, supercontext, chain) tree build_expr_wfl (node, file, line, col) tree node; - char *file; + const char *file; int line, col; { - static char *last_file = 0; + static const char *last_file = 0; static tree last_filenode = NULL_TREE; register tree wfl = make_node (EXPR_WITH_FILE_LOCATION); @@ -3292,7 +3300,6 @@ build_type_attribute_variant (ttype, attribute) current_obstack = TYPE_OBSTACK (ttype); ntype = copy_node (ttype); - current_obstack = ambient_obstack; TYPE_POINTER_TO (ntype) = 0; TYPE_REFERENCE_TO (ntype) = 0; @@ -3301,7 +3308,7 @@ build_type_attribute_variant (ttype, attribute) /* Create a new main variant of TYPE. */ TYPE_MAIN_VARIANT (ntype) = ntype; TYPE_NEXT_VARIANT (ntype) = 0; - TYPE_READONLY (ntype) = TYPE_VOLATILE (ntype) = 0; + set_type_quals (ntype, TYPE_UNQUALIFIED); hashcode = TYPE_HASH (TREE_CODE (ntype)) + TYPE_HASH (TREE_TYPE (ntype)) @@ -3326,8 +3333,13 @@ build_type_attribute_variant (ttype, attribute) } ntype = type_hash_canon (hashcode, ntype); - ttype = build_type_variant (ntype, TYPE_READONLY (ttype), - TYPE_VOLATILE (ttype)); + ttype = build_qualified_type (ntype, TYPE_QUALS (ttype)); + + /* We must restore the current obstack after the type_hash_canon call, + because type_hash_canon calls type_hash_add for permanent types, and + then type_hash_add calls oballoc expecting to get something permanent + back. */ + current_obstack = ambient_obstack; } return ttype; @@ -3339,11 +3351,12 @@ build_type_attribute_variant (ttype, attribute) int valid_machine_attribute (attr_name, attr_args, decl, type) - tree attr_name, attr_args; - tree decl; - tree type; + tree attr_name; + tree attr_args ATTRIBUTE_UNUSED; + tree decl ATTRIBUTE_UNUSED; + tree type ATTRIBUTE_UNUSED; { - int valid = 0; + int validated = 0; #ifdef VALID_MACHINE_DECL_ATTRIBUTE tree decl_attr_list = decl != 0 ? DECL_MACHINE_ATTRIBUTES (decl) : 0; #endif @@ -3373,12 +3386,15 @@ valid_machine_attribute (attr_name, attr_args, decl, type) decl = build_decl_attribute_variant (decl, decl_attr_list); } - valid = 1; + validated = 1; } #endif #ifdef VALID_MACHINE_TYPE_ATTRIBUTE - if (VALID_MACHINE_TYPE_ATTRIBUTE (type, type_attr_list, attr_name, attr_args)) + if (validated) + /* Don't apply the attribute to both the decl and the type. */; + else if (VALID_MACHINE_TYPE_ATTRIBUTE (type, type_attr_list, attr_name, + attr_args)) { tree attr = lookup_attribute (IDENTIFIER_POINTER (attr_name), type_attr_list); @@ -3404,7 +3420,7 @@ valid_machine_attribute (attr_name, attr_args, decl, type) } if (decl != 0) TREE_TYPE (decl) = type; - valid = 1; + validated = 1; } /* Handle putting a type attribute on pointer-to-function-type by putting @@ -3430,12 +3446,19 @@ valid_machine_attribute (attr_name, attr_args, decl, type) if (decl != 0) TREE_TYPE (decl) = build_pointer_type (inner_type); + else + { + /* Clear TYPE_POINTER_TO for the old inner type, since + `type' won't be pointing to it anymore. */ + TYPE_POINTER_TO (TREE_TYPE (type)) = NULL_TREE; + TREE_TYPE (type) = inner_type; + } - valid = 1; + validated = 1; } #endif - return valid; + return validated; } /* Return non-zero if IDENT is a valid name for attribute ATTR, @@ -3448,7 +3471,7 @@ valid_machine_attribute (attr_name, attr_args, decl, type) int is_attribute_p (attr, ident) - char *attr; + const char *attr; tree ident; { int ident_len, attr_len; @@ -3493,7 +3516,7 @@ is_attribute_p (attr, ident) tree lookup_attribute (attr_name, list) - char *attr_name; + const char *attr_name; tree list; { tree l; @@ -3579,45 +3602,44 @@ merge_machine_decl_attributes (olddecl, newdecl) #endif } -/* Return a type like TYPE except that its TYPE_READONLY is CONSTP - and its TYPE_VOLATILE is VOLATILEP. +/* Set the type qualifiers for TYPE to TYPE_QUALS, which is a bitmask + of the various TYPE_QUAL values. */ - Such variant types already made are recorded so that duplicates - are not made. +static void +set_type_quals (type, type_quals) + tree type; + int type_quals; +{ + TYPE_READONLY (type) = (type_quals & TYPE_QUAL_CONST) != 0; + TYPE_VOLATILE (type) = (type_quals & TYPE_QUAL_VOLATILE) != 0; + TYPE_RESTRICT (type) = (type_quals & TYPE_QUAL_RESTRICT) != 0; +} - A variant types should never be used as the type of an expression. - Always copy the variant information into the TREE_READONLY - and TREE_THIS_VOLATILE of the expression, and then give the expression - as its type the "main variant", the variant whose TYPE_READONLY - and TYPE_VOLATILE are zero. Use TYPE_MAIN_VARIANT to find the - main variant. */ +/* Given a type node TYPE and a TYPE_QUALIFIER_SET, return a type for + the same kind of data as TYPE describes. Variants point to the + "main variant" (which has no qualifiers set) via TYPE_MAIN_VARIANT, + and it points to a chain of other variants so that duplicate + variants are never made. Only main variants should ever appear as + types of expressions. */ tree -build_type_variant (type, constp, volatilep) +build_qualified_type (type, type_quals) tree type; - int constp, volatilep; + int type_quals; { register tree t; - - /* Treat any nonzero argument as 1. */ - constp = !!constp; - volatilep = !!volatilep; - + /* Search the chain of variants to see if there is already one there just like the one we need to have. If so, use that existing one. We must preserve the TYPE_NAME, since there is code that depends on this. */ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - if (constp == TYPE_READONLY (t) && volatilep == TYPE_VOLATILE (t) - && TYPE_NAME (t) == TYPE_NAME (type)) + if (TYPE_QUALS (t) == type_quals && TYPE_NAME (t) == TYPE_NAME (type)) return t; /* We need a new one. */ - t = build_type_copy (type); - TYPE_READONLY (t) = constp; - TYPE_VOLATILE (t) = volatilep; - + set_type_quals (t, type_quals); return t; } @@ -3960,10 +3982,13 @@ simple_cst_equal (t1, t2) code2 = TREE_CODE (t2); if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR) - if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR) - return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - else - return simple_cst_equal (TREE_OPERAND (t1, 0), t2); + { + if (code2 == NOP_EXPR || code2 == CONVERT_EXPR + || code2 == NON_LVALUE_EXPR) + return simple_cst_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); + else + return simple_cst_equal (TREE_OPERAND (t1, 0), t2); + } else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR) return simple_cst_equal (t1, TREE_OPERAND (t2, 0)); @@ -4422,8 +4447,7 @@ build_complex_type (component_type) t = make_node (COMPLEX_TYPE); TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type); - TYPE_VOLATILE (t) = TYPE_VOLATILE (component_type); - TYPE_READONLY (t) = TYPE_READONLY (component_type); + set_type_quals (t, TYPE_QUALS (component_type)); /* If we already have such a type, use the old one and free this one. */ hashcode = TYPE_HASH (component_type); @@ -4745,7 +4769,7 @@ print_inline_obstack_statistics () void print_obstack_statistics (str, o) - char *str; + const char *str; struct obstack *o; { struct _obstack_chunk *chunk = o->chunk; @@ -4870,7 +4894,7 @@ append_random_chars (template) tree get_file_function_name_long (type) - char *type; + const char *type; { char *buf; register char *p; @@ -4882,8 +4906,8 @@ get_file_function_name_long (type) /* We don't have anything that we know to be unique to this translation unit, so use what we do have and throw in some randomness. */ - char *name = weak_global_object_name; - char *file = main_input_filename; + const char *name = weak_global_object_name; + const char *file = main_input_filename; if (! name) name = ""; @@ -5053,7 +5077,7 @@ tree tree_check (node, code, file, line, nofatal) tree node; enum tree_code code; - char *file; + const char *file; int line; int nofatal; { @@ -5073,7 +5097,7 @@ tree tree_class_check (node, cl, file, line, nofatal) tree node; char cl; - char *file; + const char *file; int line; int nofatal; { @@ -5092,7 +5116,7 @@ tree expr_check (node, ignored, file, line, nofatal) tree node; int ignored; - char *file; + const char *file; int line; int nofatal; { @@ -5121,7 +5145,8 @@ expr_check (node, ignored, file, line, nofatal) /* Return the alias set for T, which may be either a type or an expression. */ -int get_alias_set (t) +int +get_alias_set (t) tree t; { if (!flag_strict_aliasing || !lang_get_alias_set) @@ -5131,3 +5156,15 @@ int get_alias_set (t) else return (*lang_get_alias_set) (t); } + +/* Return a brand-new alias set. */ + +int +new_alias_set () +{ + static int last_alias_set; + if (flag_strict_aliasing) + return ++last_alias_set; + else + return 0; +} |