X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Ftree.c;h=81c54d0edf49f6fa70548976dcc988bf1f1ee2ca;hb=f5ef996258725dd451733c21e2bba88c87019646;hp=61f17de706deaccbfb443aff2af252e84a306b40;hpb=20a8f962f826727be1912aaeb411681561241240;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/tree.c b/gcc/tree.c index 61f17de706d..81c54d0edf4 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1194,8 +1194,8 @@ build_string (int len, const char *str) TREE_CONSTANT (s) = 1; TREE_INVARIANT (s) = 1; TREE_STRING_LENGTH (s) = len; - memcpy (CONST_CAST (TREE_STRING_POINTER (s)), str, len); - ((char *) CONST_CAST (TREE_STRING_POINTER (s)))[len] = '\0'; + memcpy (s->string.str, str, len); + s->string.str[len] = '\0'; return s; } @@ -3403,7 +3403,7 @@ expand_location (source_location loc) } else { - const struct line_map *map = linemap_lookup (&line_table, loc); + const struct line_map *map = linemap_lookup (line_table, loc); xloc.file = map->to_file; xloc.line = SOURCE_LINE (map, loc); xloc.column = SOURCE_COLUMN (map, loc); @@ -3419,6 +3419,8 @@ expand_location (source_location loc) void annotate_with_file_line (tree node, const char *file, int line) { + location_t *new_loc; + /* Roughly one percent of the calls to this function are to annotate a node with the same information already attached to that node! Just return instead of wasting memory. */ @@ -3443,10 +3445,11 @@ annotate_with_file_line (tree node, const char *file, int line) return; } - SET_EXPR_LOCUS (node, ggc_alloc (sizeof (location_t))); - EXPR_LINENO (node) = line; - EXPR_FILENAME (node) = file; - last_annotated_node = EXPR_LOCUS (node); + new_loc = GGC_NEW (location_t); + new_loc->file = file; + new_loc->line = line; + SET_EXPR_LOCUS (node, new_loc); + last_annotated_node = new_loc; } void @@ -3509,13 +3512,13 @@ expr_locus (const_tree node) { #ifdef USE_MAPPED_LOCATION if (GIMPLE_STMT_P (node)) - return &GIMPLE_STMT_LOCUS (node); - return EXPR_P (node) ? &node->exp.locus : (location_t *) NULL; + return CONST_CAST (source_location *, &GIMPLE_STMT_LOCUS (node)); + return (EXPR_P (node) + ? CONST_CAST (source_location *, &node->exp.locus) + : (source_location *) NULL); #else if (GIMPLE_STMT_P (node)) return GIMPLE_STMT_LOCUS (node); - /* ?? The cast below was originally "(location_t *)" in the macro, - but that makes no sense. ?? */ return EXPR_P (node) ? node->exp.locus : (source_locus) NULL; #endif } @@ -3552,33 +3555,24 @@ set_expr_locus (tree node, #endif } -const char ** +/* Return the file name of the location of NODE. */ +const char * expr_filename (const_tree node) { -#ifdef USE_MAPPED_LOCATION if (GIMPLE_STMT_P (node)) - return &LOCATION_FILE (GIMPLE_STMT_LOCUS (node)); - return &LOCATION_FILE (EXPR_CHECK (node)->exp.locus); -#else - if (GIMPLE_STMT_P (node)) - return &GIMPLE_STMT_LOCUS (node)->file; - return &(EXPR_CHECK (node)->exp.locus->file); -#endif + return LOCATION_FILE (location_from_locus (GIMPLE_STMT_LOCUS (node))); + return LOCATION_FILE (location_from_locus (EXPR_CHECK (node)->exp.locus)); } -int * +/* Return the line number of the location of NODE. */ +int expr_lineno (const_tree node) { -#ifdef USE_MAPPED_LOCATION if (GIMPLE_STMT_P (node)) - return &LOCATION_LINE (GIMPLE_STMT_LOCUS (node)); - return &LOCATION_LINE (EXPR_CHECK (node)->exp.locus); -#else - if (GIMPLE_STMT_P (node)) - return &GIMPLE_STMT_LOCUS (node)->line; - return &EXPR_CHECK (node)->exp.locus->line; -#endif + return LOCATION_LINE (location_from_locus (GIMPLE_STMT_LOCUS (node))); + return LOCATION_LINE (location_from_locus (EXPR_CHECK (node)->exp.locus)); } + /* Return a declaration like DDECL except that its DECL_ATTRIBUTES is ATTRIBUTE. */ @@ -3678,12 +3672,6 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) TYPE_REFERENCE_TO (ntype) = 0; TYPE_ATTRIBUTES (ntype) = attribute; - if (TYPE_STRUCTURAL_EQUALITY_P (ttype)) - SET_TYPE_STRUCTURAL_EQUALITY (ntype); - else - TYPE_CANONICAL (ntype) - = build_qualified_type (TYPE_CANONICAL (ttype), quals); - /* Create a new main variant of TYPE. */ TYPE_MAIN_VARIANT (ntype) = ntype; TYPE_NEXT_VARIANT (ntype) = 0; @@ -3726,8 +3714,12 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) /* If the target-dependent attributes make NTYPE different from its canonical type, we will need to use structural equality checks for this qualified type. */ - if (!targetm.comp_type_attributes (ntype, ttype)) + ttype = build_qualified_type (ttype, TYPE_UNQUALIFIED); + if (TYPE_STRUCTURAL_EQUALITY_P (ttype) + || !targetm.comp_type_attributes (ntype, ttype)) SET_TYPE_STRUCTURAL_EQUALITY (ntype); + else + TYPE_CANONICAL (ntype) = TYPE_CANONICAL (ttype); ttype = build_qualified_type (ntype, quals); } @@ -3823,7 +3815,6 @@ lookup_attribute (const char *attr_name, tree list) if (is_attribute_with_length_p (attr_name, attr_len, TREE_PURPOSE (l))) return l; } - return NULL_TREE; } @@ -4315,9 +4306,6 @@ decl_init_priority_lookup (tree decl) struct tree_map_base in; gcc_assert (VAR_OR_FUNCTION_DECL_P (decl)); - gcc_assert (TREE_CODE (decl) == VAR_DECL - ? DECL_HAS_INIT_PRIORITY_P (decl) - : DECL_STATIC_CONSTRUCTOR (decl)); in.from = decl; h = htab_find (init_priority_for_decl, &in); return h ? h->init : DEFAULT_INIT_PRIORITY; @@ -4332,7 +4320,6 @@ decl_fini_priority_lookup (tree decl) struct tree_map_base in; gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); - gcc_assert (DECL_STATIC_DESTRUCTOR (decl)); in.from = decl; h = htab_find (init_priority_for_decl, &in); return h ? h->fini : DEFAULT_INIT_PRIORITY; @@ -4617,17 +4604,24 @@ type_hash_eq (const void *va, const void *vb) TYPE_FIELDS (b->type)))); case FUNCTION_TYPE: - return (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type) - || (TYPE_ARG_TYPES (a->type) - && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST - && TYPE_ARG_TYPES (b->type) - && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST - && type_list_equal (TYPE_ARG_TYPES (a->type), - TYPE_ARG_TYPES (b->type)))); + if (TYPE_ARG_TYPES (a->type) == TYPE_ARG_TYPES (b->type) + || (TYPE_ARG_TYPES (a->type) + && TREE_CODE (TYPE_ARG_TYPES (a->type)) == TREE_LIST + && TYPE_ARG_TYPES (b->type) + && TREE_CODE (TYPE_ARG_TYPES (b->type)) == TREE_LIST + && type_list_equal (TYPE_ARG_TYPES (a->type), + TYPE_ARG_TYPES (b->type)))) + break; + return 0; default: return 0; } + + if (lang_hooks.types.type_hash_eq != NULL) + return lang_hooks.types.type_hash_eq (a->type, b->type); + + return 1; } /* Return the cached hash value. */ @@ -4757,7 +4751,7 @@ attribute_hash_list (const_tree list, hashval_t hashcode) equivalent to l1. */ int -attribute_list_equal (tree l1, tree l2) +attribute_list_equal (const_tree l1, const_tree l2) { return attribute_list_contained (l1, l2) && attribute_list_contained (l2, l1); @@ -4772,9 +4766,9 @@ attribute_list_equal (tree l1, tree l2) correctly. */ int -attribute_list_contained (tree l1, tree l2) +attribute_list_contained (const_tree l1, const_tree l2) { - tree t1, t2; + const_tree t1, t2; /* First check the obvious, maybe the lists are identical. */ if (l1 == l2) @@ -4793,8 +4787,12 @@ attribute_list_contained (tree l1, tree l2) for (; t2 != 0; t2 = TREE_CHAIN (t2)) { - tree attr; - for (attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), l1); + const_tree attr; + /* This CONST_CAST is okay because lookup_attribute does not + modify its argument and the return value is assigned to a + const_tree. */ + for (attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), + CONST_CAST_TREE(l1)); attr != NULL_TREE; attr = lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (t2)), TREE_CHAIN (attr))) @@ -4936,7 +4934,8 @@ host_integerp (const_tree t, int pos) && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) >= 0) || (! pos && TREE_INT_CST_HIGH (t) == -1 && (HOST_WIDE_INT) TREE_INT_CST_LOW (t) < 0 - && !TYPE_UNSIGNED (TREE_TYPE (t))) + && (!TYPE_UNSIGNED (TREE_TYPE (t)) + || TYPE_IS_SIZETYPE (TREE_TYPE (t)))) || (pos && TREE_INT_CST_HIGH (t) == 0))); } @@ -5946,10 +5945,10 @@ build_offset_type (tree basetype, tree type) if (TYPE_STRUCTURAL_EQUALITY_P (basetype) || TYPE_STRUCTURAL_EQUALITY_P (type)) SET_TYPE_STRUCTURAL_EQUALITY (t); - else if (TYPE_CANONICAL (basetype) != basetype + else if (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)) != basetype || TYPE_CANONICAL (type) != type) TYPE_CANONICAL (t) - = build_offset_type (TYPE_CANONICAL (basetype), + = build_offset_type (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)), TYPE_CANONICAL (type)); } @@ -5985,10 +5984,8 @@ build_complex_type (tree component_type) = build_complex_type (TYPE_CANONICAL (component_type)); } - /* If we are writing Dwarf2 output we need to create a name, - since complex is a fundamental type. */ - if ((write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) - && ! TYPE_NAME (t)) + /* We need to create a name, since complex is a fundamental type. */ + if (! TYPE_NAME (t)) { const char *name; if (component_type == char_type_node) @@ -6354,6 +6351,19 @@ get_type_static_bounds (const_tree type, mpz_t min, mpz_t max) } } +/* auto_var_in_fn_p is called to determine whether VAR is an automatic + variable defined in function FN. */ + +bool +auto_var_in_fn_p (const_tree var, const_tree fn) +{ + return (DECL_P (var) && DECL_CONTEXT (var) == fn + && (((TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL) + && ! TREE_STATIC (var)) + || TREE_CODE (var) == LABEL_DECL + || TREE_CODE (var) == RESULT_DECL)); +} + /* Subprogram of following function. Called by walk_tree. Return *TP if it is an automatic variable or parameter of the @@ -6368,7 +6378,7 @@ find_var_from_fn (tree *tp, int *walk_subtrees, void *data) *walk_subtrees = 0; else if (DECL_P (*tp) - && lang_hooks.tree_inlining.auto_var_in_fn_p (*tp, fn)) + && auto_var_in_fn_p (*tp, fn)) return *tp; return NULL_TREE; @@ -7959,7 +7969,7 @@ range_in_array_bounds_p (tree ref) location. */ bool -needs_to_live_in_memory (tree t) +needs_to_live_in_memory (const_tree t) { if (TREE_CODE (t) == SSA_NAME) t = SSA_NAME_VAR (t); @@ -8693,4 +8703,92 @@ call_expr_arglist (tree exp) return arglist; } +/* Return true if TYPE has a variable argument list. */ + +bool +stdarg_p (tree fntype) +{ + function_args_iterator args_iter; + tree n = NULL_TREE, t; + + if (!fntype) + return false; + + FOREACH_FUNCTION_ARGS(fntype, t, args_iter) + { + n = t; + } + + return n != NULL_TREE && n != void_type_node; +} + +/* Return true if TYPE has a prototype. */ + +bool +prototype_p (tree fntype) +{ + tree t; + + gcc_assert (fntype != NULL_TREE); + + t = TYPE_ARG_TYPES (fntype); + return (t != NULL_TREE); +} + +/* Return the number of arguments that a function has. */ + +int +function_args_count (tree fntype) +{ + function_args_iterator args_iter; + tree t; + int num = 0; + + if (fntype) + { + FOREACH_FUNCTION_ARGS(fntype, t, args_iter) + { + num++; + } + } + + return num; +} + +/* If BLOCK is inlined from an __attribute__((__artificial__)) + routine, return pointer to location from where it has been + called. */ +location_t * +block_nonartificial_location (tree block) +{ + location_t *ret = NULL; + + while (block && TREE_CODE (block) == BLOCK + && BLOCK_ABSTRACT_ORIGIN (block)) + { + tree ao = BLOCK_ABSTRACT_ORIGIN (block); + + while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao)) + ao = BLOCK_ABSTRACT_ORIGIN (ao); + + if (TREE_CODE (ao) == FUNCTION_DECL) + { + /* If AO is an artificial inline, point RET to the + call site locus at which it has been inlined and continue + the loop, in case AO's caller is also an artificial + inline. */ + if (DECL_DECLARED_INLINE_P (ao) + && lookup_attribute ("artificial", DECL_ATTRIBUTES (ao))) + ret = &BLOCK_SOURCE_LOCATION (block); + else + break; + } + else if (TREE_CODE (ao) != BLOCK) + break; + + block = BLOCK_SUPERCONTEXT (block); + } + return ret; +} + #include "gt-tree.h"