X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Ftree.c;h=24482af95d8e37b2dc27d99337bb4ff54f7b335a;hp=a036439cc3f7f9b97e272ae3d48e26ea5ef7b5b9;hb=9301af8d8e0792c097c5f18352730afecbc290be;hpb=c8de116dd87b9f7a0e0c2cb5713356d9a83069f7 diff --git a/gcc/tree.c b/gcc/tree.c index a036439cc3f..24482af95d8 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1,6 +1,6 @@ /* Language-independent node constructors for parse phase of GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "except.h" #include "debug.h" +#include "intl.h" /* Tree code classes. */ @@ -152,6 +153,9 @@ static const char * const tree_node_kind_names[] = { static GTY(()) int next_decl_uid; /* Unique id for next type created. */ static GTY(()) int next_type_uid = 1; +/* Unique id for next debug decl created. Use negative numbers, + to catch erroneous uses. */ +static GTY(()) int next_debug_decl_uid; /* Since we cannot rehash a type after it is in the table, we have to keep the hash code. */ @@ -192,13 +196,13 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node))) /* General tree->tree mapping structure for use in hash tables. */ -static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) +static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) htab_t debug_expr_for_decl; -static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) +static GTY ((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) htab_t value_expr_for_decl; -static GTY ((if_marked ("tree_priority_map_marked_p"), +static GTY ((if_marked ("tree_priority_map_marked_p"), param_is (struct tree_priority_map))) htab_t init_priority_for_decl; @@ -269,7 +273,7 @@ static inline enum tree_node_structure_enum tree_node_structure_for_code (enum tree_code code) { switch (TREE_CODE_CLASS (code)) - { + { case tcc_declaration: { switch (code) @@ -284,6 +288,8 @@ tree_node_structure_for_code (enum tree_code code) return TS_LABEL_DECL; case RESULT_DECL: return TS_RESULT_DECL; + case DEBUG_EXPR_DECL: + return TS_DECL_WRTL; case CONST_DECL: return TS_CONST_DECL; case TYPE_DECL: @@ -361,7 +367,7 @@ initialize_tree_contains_struct (void) MARK_TS_COMMON (C); \ tree_contains_struct[C][TS_DECL_MINIMAL] = 1; \ } while (0) - + #define MARK_TS_DECL_COMMON(C) \ do { \ MARK_TS_DECL_MINIMAL (C); \ @@ -537,7 +543,7 @@ init_ttree (void) int_cst_hash_table = htab_create_ggc (1024, int_cst_hash_hash, int_cst_hash_eq, NULL); - + int_cst_node = make_node (INTEGER_CST); cl_option_hash_table = htab_create_ggc (64, cl_option_hash_hash, @@ -578,7 +584,7 @@ decl_assembler_name_equal (tree decl, const_tree asmname) decl_str = IDENTIFIER_POINTER (decl_asmname); asmname_str = IDENTIFIER_POINTER (asmname); - + /* If the target assembler name was set by the user, things are trickier. We have a leading '*' to begin with. After that, it's arguable what @@ -667,6 +673,8 @@ tree_code_size (enum tree_code code) return sizeof (struct tree_type_decl); case FUNCTION_DECL: return sizeof (struct tree_function_decl); + case DEBUG_EXPR_DECL: + return sizeof (struct tree_decl_with_rtl); default: return sizeof (struct tree_decl_non_common); } @@ -836,7 +844,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) break; } break; - + default: gcc_unreachable (); } @@ -872,7 +880,13 @@ make_node_stat (enum tree_code code MEM_STAT_DECL) DECL_ALIGN (t) = 1; } DECL_SOURCE_LOCATION (t) = input_location; - DECL_UID (t) = next_decl_uid++; + if (TREE_CODE (t) == DEBUG_EXPR_DECL) + DECL_UID (t) = --next_debug_decl_uid; + else + { + DECL_UID (t) = next_decl_uid++; + SET_DECL_PT_UID (t, -1); + } if (TREE_CODE (t) == LABEL_DECL) LABEL_DECL_UID (t) = -1; @@ -944,11 +958,19 @@ copy_node_stat (tree node MEM_STAT_DECL) TREE_CHAIN (t) = 0; TREE_ASM_WRITTEN (t) = 0; TREE_VISITED (t) = 0; - t->base.ann = 0; + if (code == VAR_DECL || code == PARM_DECL || code == RESULT_DECL) + *DECL_VAR_ANN_PTR (t) = 0; if (TREE_CODE_CLASS (code) == tcc_declaration) { - DECL_UID (t) = next_decl_uid++; + if (code == DEBUG_EXPR_DECL) + DECL_UID (t) = --next_debug_decl_uid; + else + { + DECL_UID (t) = next_decl_uid++; + if (DECL_PT_UID_SET_P (node)) + SET_DECL_PT_UID (t, DECL_PT_UID (node)); + } if ((TREE_CODE (node) == PARM_DECL || TREE_CODE (node) == VAR_DECL) && DECL_HAS_VALUE_EXPR_P (node)) { @@ -971,7 +993,7 @@ copy_node_stat (tree node MEM_STAT_DECL) but the optimizer should catch that. */ TYPE_SYMTAB_POINTER (t) = 0; TYPE_SYMTAB_ADDRESS (t) = 0; - + /* Do not copy the values cache. */ if (TYPE_CACHED_VALUES_P(t)) { @@ -1172,7 +1194,7 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi) TREE_INT_CST_LOW (t) = low; TREE_INT_CST_HIGH (t) = hi; TREE_TYPE (t) = type; - + TREE_VEC_ELT (TYPE_CACHED_VALUES (type), ix) = t; } } @@ -1206,32 +1228,18 @@ build_int_cst_wide (tree type, unsigned HOST_WIDE_INT low, HOST_WIDE_INT hi) tree build_low_bits_mask (tree type, unsigned bits) { - unsigned HOST_WIDE_INT low; - HOST_WIDE_INT high; - unsigned HOST_WIDE_INT all_ones = ~(unsigned HOST_WIDE_INT) 0; + double_int mask; gcc_assert (bits <= TYPE_PRECISION (type)); if (bits == TYPE_PRECISION (type) && !TYPE_UNSIGNED (type)) - { - /* Sign extended all-ones mask. */ - low = all_ones; - high = -1; - } - else if (bits <= HOST_BITS_PER_WIDE_INT) - { - low = all_ones >> (HOST_BITS_PER_WIDE_INT - bits); - high = 0; - } + /* Sign extended all-ones mask. */ + mask = double_int_minus_one; else - { - bits -= HOST_BITS_PER_WIDE_INT; - low = all_ones; - high = all_ones >> (HOST_BITS_PER_WIDE_INT - bits); - } + mask = double_int_mask (bits); - return build_int_cst_wide (type, low, high); + return build_int_cst_wide (type, mask.low, mask.high); } /* Checks that X is integer constant that can be expressed in (unsigned) @@ -1441,7 +1449,7 @@ build_string (int len, const char *str) #ifdef GATHER_STATISTICS tree_node_counts[(int) c_kind]++; tree_node_sizes[(int) c_kind] += length; -#endif +#endif s = ggc_alloc_tree (length); @@ -1670,8 +1678,7 @@ integer_pow2p (const_tree expr) if (TREE_CODE (expr) != INTEGER_CST) return 0; - prec = (POINTER_TYPE_P (TREE_TYPE (expr)) - ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr))); + prec = TYPE_PRECISION (TREE_TYPE (expr)); high = TREE_INT_CST_HIGH (expr); low = TREE_INT_CST_LOW (expr); @@ -1735,9 +1742,7 @@ tree_log2 (const_tree expr) if (TREE_CODE (expr) == COMPLEX_CST) return tree_log2 (TREE_REALPART (expr)); - prec = (POINTER_TYPE_P (TREE_TYPE (expr)) - ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr))); - + prec = TYPE_PRECISION (TREE_TYPE (expr)); high = TREE_INT_CST_HIGH (expr); low = TREE_INT_CST_LOW (expr); @@ -1773,9 +1778,7 @@ tree_floor_log2 (const_tree expr) if (TREE_CODE (expr) == COMPLEX_CST) return tree_log2 (TREE_REALPART (expr)); - prec = (POINTER_TYPE_P (TREE_TYPE (expr)) - ? POINTER_SIZE : TYPE_PRECISION (TREE_TYPE (expr))); - + prec = TYPE_PRECISION (TREE_TYPE (expr)); high = TREE_INT_CST_HIGH (expr); low = TREE_INT_CST_LOW (expr); @@ -1905,6 +1908,17 @@ purpose_member (const_tree elem, tree list) return NULL_TREE; } +/* Returns element number IDX (zero-origin) of chain CHAIN, or + NULL_TREE. */ + +tree +chain_index (int idx, tree chain) +{ + for (; chain && idx > 0; --idx) + chain = TREE_CHAIN (chain); + return chain; +} + /* Return nonzero if ELEM is part of the chain CHAIN. */ int @@ -1962,6 +1976,18 @@ fields_length (const_tree type) return count; } +/* Returns the first FIELD_DECL in the TYPE_FIELDS of the RECORD_TYPE or + UNION_TYPE TYPE, or NULL_TREE if none. */ + +tree +first_field (const_tree type) +{ + tree t = TYPE_FIELDS (type); + while (t && TREE_CODE (t) != FIELD_DECL) + t = TREE_CHAIN (t); + return t; +} + /* Concatenate two chains of nodes (chained through TREE_CHAIN) by modifying the last node in chain 1 to point to chain 2. This is the Lisp primitive `nconc'. */ @@ -2003,18 +2029,6 @@ tree_last (tree chain) return chain; } -/* Return the node in a chain of nodes whose value is x, NULL if not found. */ - -tree -tree_find_value (tree chain, tree x) -{ - tree list; - for (list = chain; list; list = TREE_CHAIN (list)) - if (TREE_VALUE (list) == x) - return list; - return NULL; -} - /* Reverse the order of elements in the chain T, and return the new head of the chain (old last element). */ @@ -3631,9 +3645,9 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL) side_effects = 1; \ if (!TREE_READONLY (arg##N) \ && !CONSTANT_CLASS_P (arg##N)) \ - read_only = 0; \ + (void) (read_only = 0); \ if (!TREE_CONSTANT (arg##N)) \ - constant = 0; \ + (void) (constant = 0); \ } \ } while (0) @@ -3803,10 +3817,14 @@ build6_stat (enum tree_code code, tree tt, tree arg0, tree arg1, PROCESS_ARG(2); PROCESS_ARG(3); PROCESS_ARG(4); + if (code == TARGET_MEM_REF) + side_effects = 0; PROCESS_ARG(5); TREE_SIDE_EFFECTS (t) = side_effects; - TREE_THIS_VOLATILE (t) = 0; + TREE_THIS_VOLATILE (t) + = (code == TARGET_MEM_REF + && arg5 && TREE_THIS_VOLATILE (arg5)); return t; } @@ -3940,9 +3958,9 @@ expanded_location expand_location (source_location loc) { expanded_location xloc; - if (loc == 0) + if (loc <= BUILTINS_LOCATION) { - xloc.file = NULL; + xloc.file = loc == UNKNOWN_LOCATION ? NULL : _(""); xloc.line = 0; xloc.column = 0; xloc.sysp = 0; @@ -4035,7 +4053,7 @@ iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2) Record such modified types already made so we don't make duplicates. */ -static tree +tree build_type_attribute_qual_variant (tree ttype, tree attribute, int quals) { if (! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute)) @@ -4131,6 +4149,28 @@ build_type_attribute_variant (tree ttype, tree attribute) TYPE_QUALS (ttype)); } + +/* Reset all the fields in a binfo node BINFO. We only keep + BINFO_VIRTUALS, which is used by gimple_fold_obj_type_ref. */ + +static void +free_lang_data_in_binfo (tree binfo) +{ + unsigned i; + tree t; + + gcc_assert (TREE_CODE (binfo) == TREE_BINFO); + + BINFO_VTABLE (binfo) = NULL_TREE; + BINFO_BASE_ACCESSES (binfo) = NULL; + BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE; + BINFO_SUBVTT_INDEX (binfo) = NULL_TREE; + + for (i = 0; VEC_iterate (tree, BINFO_BASE_BINFOS (binfo), i, t); i++) + free_lang_data_in_binfo (t); +} + + /* Reset all language specific information still present in TYPE. */ static void @@ -4138,11 +4178,6 @@ free_lang_data_in_type (tree type) { gcc_assert (TYPE_P (type)); - /* Fill in the alias-set. We need to at least track zeroness here - for correctness. */ - if (lang_hooks.get_alias_set (type) == 0) - TYPE_ALIAS_SET (type) = 0; - /* Give the FE a chance to remove its own data first. */ lang_hooks.free_lang_data (type); @@ -4177,12 +4212,10 @@ free_lang_data_in_type (tree type) } } } - + /* Remove members that are not actually FIELD_DECLs from the field list of an aggregate. These occur in C++. */ - if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE - || TREE_CODE (type) == QUAL_UNION_TYPE) + if (RECORD_OR_UNION_TYPE_P (type)) { tree prev, member; @@ -4191,7 +4224,7 @@ free_lang_data_in_type (tree type) to be removed, we cannot set its TREE_CHAIN to NULL. Otherwise, we would not be able to find all the other fields in the other instances of this TREE_TYPE. - + This was causing an ICE in testsuite/g++.dg/lto/20080915.C. */ prev = NULL_TREE; member = TYPE_FIELDS (type); @@ -4216,30 +4249,7 @@ free_lang_data_in_type (tree type) TYPE_METHODS (type) = NULL_TREE; if (TYPE_BINFO (type)) - { - tree binfo = TYPE_BINFO (type); - - if (BINFO_VIRTUALS (binfo)) - { - /* If the virtual function table for BINFO contains - entries, these may be useful for folding OBJ_TYPE_REF - expressions (see gimple_fold_obj_type_ref). In that - case, we only clear the unused fields in the BINFO - structure. */ - BINFO_OFFSET (binfo) = NULL_TREE; - BINFO_VTABLE (binfo) = NULL_TREE; - BINFO_VPTR_FIELD (binfo) = NULL_TREE; - BINFO_BASE_ACCESSES (binfo) = NULL; - BINFO_INHERITANCE_CHAIN (binfo) = NULL_TREE; - BINFO_SUBVTT_INDEX (binfo) = NULL_TREE; - BINFO_VPTR_FIELD (binfo) = NULL_TREE; - } - else - { - /* Otherwise, get rid of the whole binfo data. */ - TYPE_BINFO (type) = NULL_TREE; - } - } + free_lang_data_in_binfo (TYPE_BINFO (type)); } else { @@ -4248,18 +4258,14 @@ free_lang_data_in_type (tree type) TYPE_LANG_SLOT_1 (type) = NULL_TREE; } - TYPE_CONTEXT (type) = NULL_TREE; - TYPE_STUB_DECL (type) = NULL_TREE; + if (debug_info_level < DINFO_LEVEL_TERSE + || (TYPE_CONTEXT (type) + && TREE_CODE (TYPE_CONTEXT (type)) != FUNCTION_DECL + && TREE_CODE (TYPE_CONTEXT (type)) != NAMESPACE_DECL)) + TYPE_CONTEXT (type) = NULL_TREE; - /* Remove type variants other than the main variant. This is both - wasteful and it may introduce infinite loops when the types are - read from disk and merged (since the variant will be the same - type as the main variant, traversing type variants will get into - an infinite loop). */ - if (TYPE_MAIN_VARIANT (type)) - TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (type)) = NULL_TREE; - - TYPE_NEXT_VARIANT (type) = NULL_TREE; + if (debug_info_level < DINFO_LEVEL_TERSE) + TYPE_STUB_DECL (type) = NULL_TREE; } @@ -4279,6 +4285,10 @@ need_assembler_name_p (tree decl) || DECL_ASSEMBLER_NAME_SET_P (decl)) return false; + /* Abstract decls do not need an assembler name. */ + if (DECL_ABSTRACT (decl)) + return false; + /* For VAR_DECLs, only static, public and external symbols need an assembler name. */ if (TREE_CODE (decl) == VAR_DECL @@ -4287,19 +4297,22 @@ need_assembler_name_p (tree decl) && !DECL_EXTERNAL (decl)) return false; - /* Do not set assembler name on builtins. Allow RTL expansion to - decide whether to expand inline or via a regular call. */ - if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_BUILT_IN (decl) - && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND) - return false; + if (TREE_CODE (decl) == FUNCTION_DECL) + { + /* Do not set assembler name on builtins. Allow RTL expansion to + decide whether to expand inline or via a regular call. */ + if (DECL_BUILT_IN (decl) + && DECL_BUILT_IN_CLASS (decl) != BUILT_IN_FRONTEND) + return false; - /* For FUNCTION_DECLs, only used functions and functions - represented in the callgraph need an assembler name. */ - if (TREE_CODE (decl) == FUNCTION_DECL - && cgraph_node_for_decl (decl) == NULL - && !TREE_USED (decl)) - return false; + /* Functions represented in the callgraph need an assembler name. */ + if (cgraph_get_node (decl) != NULL) + return true; + + /* Unused and not public functions don't need an assembler name. */ + if (!TREE_USED (decl) && !TREE_PUBLIC (decl)) + return false; + } return true; } @@ -4351,12 +4364,10 @@ free_lang_data_in_decl (tree decl) if (DECL_NAME (decl)) TREE_TYPE (DECL_NAME (decl)) = NULL_TREE; - if (TREE_CODE (decl) == CONST_DECL) - DECL_CONTEXT (decl) = NULL_TREE; - /* Ignore any intervening types, because we are going to clear their TYPE_CONTEXT fields. */ - if (TREE_CODE (decl) != FIELD_DECL) + if (TREE_CODE (decl) != FIELD_DECL + && TREE_CODE (decl) != FUNCTION_DECL) DECL_CONTEXT (decl) = decl_function_context (decl); if (DECL_CONTEXT (decl) @@ -4382,25 +4393,16 @@ free_lang_data_in_decl (tree decl) } } - if (TREE_CODE (decl) == PARM_DECL - || TREE_CODE (decl) == FIELD_DECL - || TREE_CODE (decl) == RESULT_DECL) - { - tree unit_size = DECL_SIZE_UNIT (decl); - tree size = DECL_SIZE (decl); - if ((unit_size && TREE_CODE (unit_size) != INTEGER_CST) - || (size && TREE_CODE (size) != INTEGER_CST)) - { - DECL_SIZE_UNIT (decl) = NULL_TREE; - DECL_SIZE (decl) = NULL_TREE; - } + /* ??? We could free non-constant DECL_SIZE, DECL_SIZE_UNIT + and DECL_FIELD_OFFSET. But it's cheap enough to not do + that and refrain from adding workarounds to dwarf2out.c */ - if (TREE_CODE (decl) == FIELD_DECL - && DECL_FIELD_OFFSET (decl) - && TREE_CODE (DECL_FIELD_OFFSET (decl)) != INTEGER_CST) - DECL_FIELD_OFFSET (decl) = NULL_TREE; - } - else if (TREE_CODE (decl) == FUNCTION_DECL) + /* DECL_FCONTEXT is only used for debug info generation. */ + if (TREE_CODE (decl) == FIELD_DECL + && debug_info_level < DINFO_LEVEL_TERSE) + DECL_FCONTEXT (decl) = NULL_TREE; + + if (TREE_CODE (decl) == FUNCTION_DECL) { if (gimple_has_body_p (decl)) { @@ -4449,13 +4451,14 @@ free_lang_data_in_decl (tree decl) && !TREE_STATIC (expr) && !DECL_EXTERNAL (expr)) SET_DECL_DEBUG_EXPR (decl, NULL_TREE); - if (DECL_EXTERNAL (decl)) + if (DECL_EXTERNAL (decl) + && (!TREE_STATIC (decl) || !TREE_READONLY (decl))) DECL_INITIAL (decl) = NULL_TREE; } else if (TREE_CODE (decl) == TYPE_DECL) { DECL_INITIAL (decl) = NULL_TREE; - + /* DECL_CONTEXT is overloaded as DECL_FIELD_CONTEXT for FIELD_DECLs, which should be preserved. Otherwise, we shouldn't be concerned with source-level lexical @@ -4469,6 +4472,9 @@ free_lang_data_in_decl (tree decl) struct free_lang_data_d { + /* Worklist to avoid excessive recursion. */ + VEC(tree,heap) *worklist; + /* Set of traversed objects. Used to avoid duplicate visits. */ struct pointer_set_t *pset; @@ -4530,59 +4536,82 @@ add_tree_to_fld_list (tree t, struct free_lang_data_d *fld) gcc_unreachable (); } +/* Push tree node T into FLD->WORKLIST. */ + +static inline void +fld_worklist_push (tree t, struct free_lang_data_d *fld) +{ + if (t && !is_lang_specific (t) && !pointer_set_contains (fld->pset, t)) + VEC_safe_push (tree, heap, fld->worklist, (t)); +} + /* Operand callback helper for free_lang_data_in_node. *TP is the subtree operand being considered. */ static tree -find_decls_types_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *data) +find_decls_types_r (tree *tp, int *ws, void *data) { tree t = *tp; struct free_lang_data_d *fld = (struct free_lang_data_d *) data; + if (TREE_CODE (t) == TREE_LIST) + return NULL_TREE; + + /* Language specific nodes will be removed, so there is no need + to gather anything under them. */ + if (is_lang_specific (t)) + { + *ws = 0; + return NULL_TREE; + } + if (DECL_P (t)) { /* Note that walk_tree does not traverse every possible field in decls, so we have to do our own traversals here. */ add_tree_to_fld_list (t, fld); - walk_tree (&DECL_NAME (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_CONTEXT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_SIZE (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_SIZE_UNIT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_INITIAL (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_ATTRIBUTES (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_ABSTRACT_ORIGIN (t), find_decls_types_r, fld, fld->pset); + fld_worklist_push (DECL_NAME (t), fld); + fld_worklist_push (DECL_CONTEXT (t), fld); + fld_worklist_push (DECL_SIZE (t), fld); + fld_worklist_push (DECL_SIZE_UNIT (t), fld); + + /* We are going to remove everything under DECL_INITIAL for + TYPE_DECLs. No point walking them. */ + if (TREE_CODE (t) != TYPE_DECL) + fld_worklist_push (DECL_INITIAL (t), fld); + + fld_worklist_push (DECL_ATTRIBUTES (t), fld); + fld_worklist_push (DECL_ABSTRACT_ORIGIN (t), fld); if (TREE_CODE (t) == FUNCTION_DECL) { - walk_tree (&DECL_ARGUMENTS (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_RESULT (t), find_decls_types_r, fld, fld->pset); + fld_worklist_push (DECL_ARGUMENTS (t), fld); + fld_worklist_push (DECL_RESULT (t), fld); } else if (TREE_CODE (t) == TYPE_DECL) { - walk_tree (&DECL_ARGUMENT_FLD (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_VINDEX (t), find_decls_types_r, fld, fld->pset); + fld_worklist_push (DECL_ARGUMENT_FLD (t), fld); + fld_worklist_push (DECL_VINDEX (t), fld); } else if (TREE_CODE (t) == FIELD_DECL) { - walk_tree (&DECL_FIELD_OFFSET (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_BIT_FIELD_TYPE (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_QUALIFIER (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_FIELD_BIT_OFFSET (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_FCONTEXT (t), find_decls_types_r, fld, fld->pset); + fld_worklist_push (DECL_FIELD_OFFSET (t), fld); + fld_worklist_push (DECL_BIT_FIELD_TYPE (t), fld); + fld_worklist_push (DECL_QUALIFIER (t), fld); + fld_worklist_push (DECL_FIELD_BIT_OFFSET (t), fld); + fld_worklist_push (DECL_FCONTEXT (t), fld); } else if (TREE_CODE (t) == VAR_DECL) { - walk_tree (&DECL_SECTION_NAME (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_COMDAT_GROUP (t), find_decls_types_r, fld, - fld->pset); + fld_worklist_push (DECL_SECTION_NAME (t), fld); + fld_worklist_push (DECL_COMDAT_GROUP (t), fld); } + + if (TREE_CODE (t) != FIELD_DECL) + fld_worklist_push (TREE_CHAIN (t), fld); + *ws = 0; } else if (TYPE_P (t)) { @@ -4590,37 +4619,79 @@ find_decls_types_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *data) types, so we have to do our own traversals here. */ add_tree_to_fld_list (t, fld); - walk_tree (&TYPE_CACHED_VALUES (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_SIZE (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_SIZE_UNIT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_ATTRIBUTES (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_POINTER_TO (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_REFERENCE_TO (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_NAME (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_MINVAL (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_MAXVAL (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_NEXT_VARIANT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_MAIN_VARIANT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_CONTEXT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_CANONICAL (t), find_decls_types_r, fld, fld->pset); - } - - if (TREE_TYPE (t)) - walk_tree (&TREE_TYPE (t), find_decls_types_r, fld, fld->pset); + if (!RECORD_OR_UNION_TYPE_P (t)) + fld_worklist_push (TYPE_CACHED_VALUES (t), fld); + fld_worklist_push (TYPE_SIZE (t), fld); + fld_worklist_push (TYPE_SIZE_UNIT (t), fld); + fld_worklist_push (TYPE_ATTRIBUTES (t), fld); + fld_worklist_push (TYPE_POINTER_TO (t), fld); + fld_worklist_push (TYPE_REFERENCE_TO (t), fld); + fld_worklist_push (TYPE_NAME (t), fld); + fld_worklist_push (TYPE_MINVAL (t), fld); + if (!RECORD_OR_UNION_TYPE_P (t)) + fld_worklist_push (TYPE_MAXVAL (t), fld); + fld_worklist_push (TYPE_MAIN_VARIANT (t), fld); + fld_worklist_push (TYPE_NEXT_VARIANT (t), fld); + fld_worklist_push (TYPE_CONTEXT (t), fld); + fld_worklist_push (TYPE_CANONICAL (t), fld); + + if (RECORD_OR_UNION_TYPE_P (t) && TYPE_BINFO (t)) + { + unsigned i; + tree tem; + for (i = 0; VEC_iterate (tree, BINFO_BASE_BINFOS (TYPE_BINFO (t)), + i, tem); ++i) + fld_worklist_push (TREE_TYPE (tem), fld); + tem = BINFO_VIRTUALS (TYPE_BINFO (t)); + if (tem + /* The Java FE overloads BINFO_VIRTUALS for its own purpose. */ + && TREE_CODE (tem) == TREE_LIST) + do + { + fld_worklist_push (TREE_VALUE (tem), fld); + tem = TREE_CHAIN (tem); + } + while (tem); + } + if (RECORD_OR_UNION_TYPE_P (t)) + { + tree tem; + /* Push all TYPE_FIELDS - there can be interleaving interesting + and non-interesting things. */ + tem = TYPE_FIELDS (t); + while (tem) + { + if (TREE_CODE (tem) == FIELD_DECL) + fld_worklist_push (tem, fld); + tem = TREE_CHAIN (tem); + } + } - /* Do not recurse into TREE_CHAIN to avoid blowing up the stack. */ - for (tp = &TREE_CHAIN (t); *tp; tp = &TREE_CHAIN (*tp)) - { - tree saved_chain = TREE_CHAIN (*tp); - TREE_CHAIN (*tp) = NULL_TREE; - walk_tree (tp, find_decls_types_r, fld, fld->pset); - TREE_CHAIN (*tp) = saved_chain; + fld_worklist_push (TREE_CHAIN (t), fld); + *ws = 0; } + fld_worklist_push (TREE_TYPE (t), fld); + return NULL_TREE; } +/* Find decls and types in T. */ + +static void +find_decls_types (tree t, struct free_lang_data_d *fld) +{ + while (1) + { + if (!pointer_set_contains (fld->pset, t)) + walk_tree (&t, find_decls_types_r, fld, fld->pset); + if (VEC_empty (tree, fld->worklist)) + break; + t = VEC_pop (tree, fld->worklist); + } +} + /* Translate all the types in LIST with the corresponding runtime types. */ @@ -4653,23 +4724,36 @@ get_eh_types_for_runtime (tree list) static void find_decls_types_in_eh_region (eh_region r, struct free_lang_data_d *fld) { - if (r == NULL) - return; - - /* The types referenced in R must first be changed to the EH types - used at runtime. This removes references to FE types in the - region. */ - if (r->type == ERT_CATCH) + switch (r->type) { - tree list = r->u.eh_catch.type_list; - r->u.eh_catch.type_list = get_eh_types_for_runtime (list); - walk_tree (&r->u.eh_catch.type_list, find_decls_types_r, fld, fld->pset); - } - else if (r->type == ERT_ALLOWED_EXCEPTIONS) - { - tree list = r->u.allowed.type_list; - r->u.allowed.type_list = get_eh_types_for_runtime (list); + case ERT_CLEANUP: + break; + + case ERT_TRY: + { + eh_catch c; + + /* The types referenced in each catch must first be changed to the + EH types used at runtime. This removes references to FE types + in the region. */ + for (c = r->u.eh_try.first_catch; c ; c = c->next_catch) + { + c->type_list = get_eh_types_for_runtime (c->type_list); + walk_tree (&c->type_list, find_decls_types_r, fld, fld->pset); + } + } + break; + + case ERT_ALLOWED_EXCEPTIONS: + r->u.allowed.type_list + = get_eh_types_for_runtime (r->u.allowed.type_list); walk_tree (&r->u.allowed.type_list, find_decls_types_r, fld, fld->pset); + break; + + case ERT_MUST_NOT_THROW: + walk_tree (&r->u.must_not_throw.failure_decl, + find_decls_types_r, fld, fld->pset); + break; } } @@ -4687,7 +4771,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) struct function *fn; tree t; - walk_tree (&n->decl, find_decls_types_r, fld, fld->pset); + find_decls_types (n->decl, fld); if (!gimple_has_body_p (n->decl)) return; @@ -4698,23 +4782,14 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) /* Traverse locals. */ for (t = fn->local_decls; t; t = TREE_CHAIN (t)) - { - tree *tp = &TREE_VALUE (t); - tree saved_chain = TREE_CHAIN (*tp); - TREE_CHAIN (*tp) = NULL_TREE; - walk_tree (tp, find_decls_types_r, fld, fld->pset); - TREE_CHAIN (*tp) = saved_chain; - } + find_decls_types (TREE_VALUE (t), fld); /* Traverse EH regions in FN. */ - if (fn->eh->region_array) - { - unsigned i; - eh_region r; - - for (i = 0; VEC_iterate (eh_region, fn->eh->region_array, i, r); i++) - find_decls_types_in_eh_region (r, fld); - } + { + eh_region r; + FOR_ALL_EH_REGION_FN (r, fn) + find_decls_types_in_eh_region (r, fld); + } /* Traverse every statement in FN. */ FOR_EACH_BB_FN (bb, fn) @@ -4729,7 +4804,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) for (i = 0; i < gimple_phi_num_args (phi); i++) { tree *arg_p = gimple_phi_arg_def_ptr (phi, i); - walk_tree (arg_p, find_decls_types_r, fld, fld->pset); + find_decls_types (*arg_p, fld); } } @@ -4739,8 +4814,8 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) for (i = 0; i < gimple_num_ops (stmt); i++) { - tree *arg_p = gimple_op_ptr (stmt, i); - walk_tree (arg_p, find_decls_types_r, fld, fld->pset); + tree arg = gimple_op (stmt, i); + find_decls_types (arg, fld); } } } @@ -4756,7 +4831,34 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) static void find_decls_types_in_var (struct varpool_node *v, struct free_lang_data_d *fld) { - walk_tree (&v->decl, find_decls_types_r, fld, fld->pset); + find_decls_types (v->decl, fld); +} + +/* If T needs an assembler name, have one created for it. */ + +void +assign_assembler_name_if_neeeded (tree t) +{ + if (need_assembler_name_p (t)) + { + /* When setting DECL_ASSEMBLER_NAME, the C++ mangler may emit + diagnostics that use input_location to show locus + information. The problem here is that, at this point, + input_location is generally anchored to the end of the file + (since the parser is long gone), so we don't have a good + position to pin it to. + + To alleviate this problem, this uses the location of T's + declaration. Examples of this are + testsuite/g++.dg/template/cond2.C and + testsuite/g++.dg/template/pr35240.C. */ + location_t saved_location = input_location; + input_location = DECL_SOURCE_LOCATION (t); + + decl_assembler_name (t); + + input_location = saved_location; + } } @@ -4789,6 +4891,7 @@ free_lang_data_in_cgraph (void) /* Initialize sets and arrays to store referenced decls and types. */ fld.pset = pointer_set_create (); + fld.worklist = NULL; fld.decls = VEC_alloc (tree, heap, 100); fld.types = VEC_alloc (tree, heap, 100); @@ -4797,7 +4900,7 @@ free_lang_data_in_cgraph (void) find_decls_types_in_node (n, &fld); for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++) - walk_tree (&p->decl, find_decls_types_r, &fld, fld.pset); + find_decls_types (p->decl, &fld); /* Find decls and types in every varpool symbol. */ for (v = varpool_nodes_queue; v; v = v->next_needed) @@ -4807,26 +4910,7 @@ free_lang_data_in_cgraph (void) now because free_lang_data_in_decl will invalidate data needed for mangling. This breaks mangling on interdependent decls. */ for (i = 0; VEC_iterate (tree, fld.decls, i, t); i++) - if (need_assembler_name_p (t)) - { - /* When setting DECL_ASSEMBLER_NAME, the C++ mangler may emit - diagnostics that use input_location to show locus - information. The problem here is that, at this point, - input_location is generally anchored to the end of the file - (since the parser is long gone), so we don't have a good - position to pin it to. - - To alleviate this problem, this uses the location of T's - declaration. Examples of this are - testsuite/g++.dg/template/cond2.C and - testsuite/g++.dg/template/pr35240.C. */ - location_t saved_location = input_location; - input_location = DECL_SOURCE_LOCATION (t); - - decl_assembler_name (t); - - input_location = saved_location; - } + assign_assembler_name_if_neeeded (t); /* Traverse every decl found freeing its language data. */ for (i = 0; VEC_iterate (tree, fld.decls, i, t); i++) @@ -4837,6 +4921,7 @@ free_lang_data_in_cgraph (void) free_lang_data_in_type (t); pointer_set_destroy (fld.pset); + VEC_free (tree, heap, fld.worklist); VEC_free (tree, heap, fld.decls); VEC_free (tree, heap, fld.types); } @@ -4847,6 +4932,19 @@ free_lang_data_in_cgraph (void) static unsigned free_lang_data (void) { + unsigned i; + + /* If we are the LTO frontend we have freed lang-specific data already. */ + if (in_lto_p + || !flag_generate_lto) + return 0; + + /* Allocate and assign alias sets to the standard integer types + while the slots are still in the way the frontends generated them. */ + for (i = 0; i < itk_none; ++i) + if (integer_types[i]) + TYPE_ALIAS_SET (integer_types[i]) = get_alias_set (integer_types[i]); + /* Traverse the IL resetting language specific information for operands, expressions, etc. */ free_lang_data_in_cgraph (); @@ -4868,9 +4966,15 @@ free_lang_data (void) boolean_true_node = TYPE_MAX_VALUE (boolean_type_node); } - /* Reset some langhooks. */ + /* Unify char_type_node with its properly signed variant. */ + if (TYPE_UNSIGNED (char_type_node)) + unsigned_char_type_node = char_type_node; + else + signed_char_type_node = char_type_node; + + /* Reset some langhooks. Do not reset types_compatible_p, it may + still be used indirectly via the get_alias_set langhook. */ lang_hooks.callgraph.analyze_expr = NULL; - lang_hooks.types_compatible_p = NULL; lang_hooks.dwarf_name = lhd_dwarf_name; lang_hooks.decl_printable_name = gimple_decl_printable_name; lang_hooks.set_decl_assembler_name = lhd_set_decl_assembler_name; @@ -4885,22 +4989,12 @@ free_lang_data (void) } -/* Gate function for free_lang_data. */ - -static bool -gate_free_lang_data (void) -{ - /* FIXME. Remove after save_debug_info is working. */ - return !flag_gtoggle && debug_info_level <= DINFO_LEVEL_TERSE; -} - - -struct simple_ipa_opt_pass pass_ipa_free_lang_data = +struct simple_ipa_opt_pass pass_ipa_free_lang_data = { { SIMPLE_IPA_PASS, - NULL, /* name */ - gate_free_lang_data, /* gate */ + "*free_lang_data", /* name */ + NULL, /* gate */ free_lang_data, /* execute */ NULL, /* sub */ NULL, /* next */ @@ -4910,7 +5004,7 @@ struct simple_ipa_opt_pass pass_ipa_free_lang_data = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + TODO_ggc_collect /* todo_flags_finish */ } }; @@ -4930,10 +5024,10 @@ is_attribute_with_length_p (const char *attr, int attr_len, const_tree ident) if (TREE_CODE (ident) != IDENTIFIER_NODE) return 0; - + p = IDENTIFIER_POINTER (ident); ident_len = IDENTIFIER_LENGTH (ident); - + if (ident_len == attr_len && strcmp (attr, p) == 0) return 1; @@ -5115,12 +5209,12 @@ merge_dllimport_decl_attributes (tree old, tree new_tree) marked dllimport and a definition appears later, then the object is not dllimport'd. We also remove a `new' dllimport if the old list contains dllexport: dllexport always overrides dllimport, regardless - of the order of declaration. */ + of the order of declaration. */ if (!VAR_OR_FUNCTION_DECL_P (new_tree)) delete_dllimport_p = 0; else if (DECL_DLLIMPORT_P (new_tree) && lookup_attribute ("dllexport", DECL_ATTRIBUTES (old))) - { + { DECL_DLLIMPORT_P (new_tree) = 0; warning (OPT_Wattributes, "%q+D already declared with dllexport attribute: " "dllimport ignored", new_tree); @@ -5146,7 +5240,7 @@ merge_dllimport_decl_attributes (tree old, tree new_tree) } /* Let an inline definition silently override the external reference, - but otherwise warn about attribute inconsistency. */ + but otherwise warn about attribute inconsistency. */ else if (TREE_CODE (new_tree) == VAR_DECL || !DECL_DECLARED_INLINE_P (new_tree)) warning (OPT_Wattributes, "%q+D redeclared without dllimport attribute: " @@ -5157,11 +5251,11 @@ merge_dllimport_decl_attributes (tree old, tree new_tree) a = merge_attributes (DECL_ATTRIBUTES (old), DECL_ATTRIBUTES (new_tree)); - if (delete_dllimport_p) + if (delete_dllimport_p) { tree prev, t; - const size_t attr_len = strlen ("dllimport"); - + const size_t attr_len = strlen ("dllimport"); + /* Scan the list for dllimport and delete it. */ for (prev = NULL_TREE, t = a; t; prev = t, t = TREE_CHAIN (t)) { @@ -5242,7 +5336,7 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags, any damage. */ if (is_dllimport) { - /* Honor any target-specific overrides. */ + /* Honor any target-specific overrides. */ if (!targetm.valid_dllimport_attribute_p (node)) *no_add_attrs = true; @@ -5250,7 +5344,7 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags, && DECL_DECLARED_INLINE_P (node)) { warning (OPT_Wattributes, "inline function %q+D declared as " - " dllimport: attribute ignored", node); + " dllimport: attribute ignored", node); *no_add_attrs = true; } /* Like MS, treat definition of dllimported variables and @@ -5307,7 +5401,7 @@ handle_dll_attribute (tree * pnode, tree name, tree args, int flags, if (DECL_VISIBILITY_SPECIFIED (node) && DECL_VISIBILITY (node) != VISIBILITY_DEFAULT) error ("%qE implies default visibility, but %qD has already " - "been declared with a different visibility", + "been declared with a different visibility", name, node); DECL_VISIBILITY (node) = VISIBILITY_DEFAULT; DECL_VISIBILITY_SPECIFIED (node) = 1; @@ -5327,6 +5421,7 @@ set_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; + TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals); } /* Returns true iff CAND is equivalent to BASE with TYPE_QUALS. */ @@ -5392,7 +5487,7 @@ build_qualified_type (tree type, int type_quals) else /* T is its own canonical type. */ TYPE_CANONICAL (t) = t; - + } return t; @@ -5407,7 +5502,7 @@ tree build_distinct_type_copy (tree type) { tree t = copy_node (type); - + TYPE_POINTER_TO (t) = 0; TYPE_REFERENCE_TO (t) = 0; @@ -5445,7 +5540,7 @@ build_variant_type_copy (tree type) /* Since we're building a variant, assume that it is a non-semantic variant. This also propagates TYPE_STRUCTURAL_EQUALITY_P. */ TYPE_CANONICAL (t) = TYPE_CANONICAL (type); - + /* Add the new type to the chain of variants of TYPE. */ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); TYPE_NEXT_VARIANT (m) = t; @@ -5552,7 +5647,7 @@ decl_init_priority_insert (tree decl, priority_type priority) gcc_assert (VAR_OR_FUNCTION_DECL_P (decl)); h = decl_priority_info (decl); h->init = priority; -} +} /* Set the finalization priority for DECL to PRIORITY. */ @@ -5564,7 +5659,7 @@ decl_fini_priority_insert (tree decl, priority_type priority) gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); h = decl_priority_info (decl); h->fini = priority; -} +} /* Print out the statistics for the DECL_DEBUG_EXPR hash table. */ @@ -5590,7 +5685,7 @@ print_value_expr_statistics (void) /* Lookup a debug expression for FROM, and return it if we find one. */ -tree +tree decl_debug_expr_lookup (tree from) { struct tree_map *h, in; @@ -5617,11 +5712,11 @@ decl_debug_expr_insert (tree from, tree to) h->to = to; loc = htab_find_slot_with_hash (debug_expr_for_decl, h, h->hash, INSERT); *(struct tree_map **) loc = h; -} +} /* Lookup a value expression for FROM, and return it if we find one. */ -tree +tree decl_value_expr_lookup (tree from) { struct tree_map *h, in; @@ -5688,7 +5783,7 @@ type_hash_eq (const void *va, const void *vb) TYPE_ATTRIBUTES (b->type)) || TYPE_ALIGN (a->type) != TYPE_ALIGN (b->type) || TYPE_MODE (a->type) != TYPE_MODE (b->type) - || (TREE_CODE (a->type) != COMPLEX_TYPE + || (TREE_CODE (a->type) != COMPLEX_TYPE && TYPE_NAME (a->type) != TYPE_NAME (b->type))) return 0; @@ -6518,7 +6613,7 @@ iterative_hash_expr (const_tree t, hashval_t val) else { gcc_assert (IS_EXPR_CODE_CLASS (tclass)); - + val = iterative_hash_object (code, val); /* Don't hash the type, that can lead to having nodes which @@ -6648,7 +6743,10 @@ build_pointer_type_for_mode (tree to_type, enum machine_mode mode, tree build_pointer_type (tree to_type) { - return build_pointer_type_for_mode (to_type, ptr_mode, false); + addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC + : TYPE_ADDR_SPACE (to_type); + enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); + return build_pointer_type_for_mode (to_type, pointer_mode, false); } /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE. */ @@ -6696,7 +6794,7 @@ build_reference_type_for_mode (tree to_type, enum machine_mode mode, if (TYPE_STRUCTURAL_EQUALITY_P (to_type)) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (to_type) != to_type) - TYPE_CANONICAL (t) + TYPE_CANONICAL (t) = build_reference_type_for_mode (TYPE_CANONICAL (to_type), mode, can_alias_all); @@ -6712,7 +6810,10 @@ build_reference_type_for_mode (tree to_type, enum machine_mode mode, tree build_reference_type (tree to_type) { - return build_reference_type_for_mode (to_type, ptr_mode, false); + addr_space_t as = to_type == error_mark_node? ADDR_SPACE_GENERIC + : TYPE_ADDR_SPACE (to_type); + enum machine_mode pointer_mode = targetm.addr_space.pointer_mode (as); + return build_reference_type_for_mode (to_type, pointer_mode, false); } /* Build a type that is compatible with t but has no cv quals anywhere @@ -6774,6 +6875,10 @@ build_index_type (tree maxval) } } +#define MAX_INT_CACHED_PREC \ + (HOST_BITS_PER_WIDE_INT > 64 ? HOST_BITS_PER_WIDE_INT : 64) +static GTY(()) tree nonstandard_integer_type_cache[2 * MAX_INT_CACHED_PREC + 2]; + /* Builds a signed or unsigned integer type of precision PRECISION. Used for C bitfields whose precision does not match that of built-in target types. */ @@ -6781,8 +6886,19 @@ tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision, int unsignedp) { - tree itype = make_node (INTEGER_TYPE); + tree itype, ret; + + if (unsignedp) + unsignedp = MAX_INT_CACHED_PREC + 1; + + if (precision <= MAX_INT_CACHED_PREC) + { + itype = nonstandard_integer_type_cache[precision + unsignedp]; + if (itype) + return itype; + } + itype = make_node (INTEGER_TYPE); TYPE_PRECISION (itype) = precision; if (unsignedp) @@ -6790,10 +6906,13 @@ build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision, else fixup_signed_type (itype); + ret = itype; if (host_integerp (TYPE_MAX_VALUE (itype), 1)) - return type_hash_canon (tree_low_cst (TYPE_MAX_VALUE (itype), 1), itype); + ret = type_hash_canon (tree_low_cst (TYPE_MAX_VALUE (itype), 1), itype); + if (precision <= MAX_INT_CACHED_PREC && lang_hooks.types.hash_types) + nonstandard_integer_type_cache[precision + unsignedp] = ret; - return itype; + return ret; } /* Create a range of some discrete type TYPE (an INTEGER_TYPE, @@ -6906,6 +7025,7 @@ build_array_type (tree elt_type, tree index_type) t = make_node (ARRAY_TYPE); TREE_TYPE (t) = elt_type; TYPE_DOMAIN (t) = index_type; + TYPE_ADDR_SPACE (t) = TYPE_ADDR_SPACE (elt_type); layout_type (t); /* If the element type is incomplete at this point we get marked for @@ -6926,7 +7046,7 @@ build_array_type (tree elt_type, tree index_type) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (elt_type) != elt_type || (index_type && TYPE_CANONICAL (index_type) != index_type)) - TYPE_CANONICAL (t) + TYPE_CANONICAL (t) = build_array_type (TYPE_CANONICAL (elt_type), index_type ? TYPE_CANONICAL (index_type) : NULL); } @@ -6947,7 +7067,7 @@ strip_array_types (tree type) } /* Computes the canonical argument types from the argument type list - ARGTYPES. + ARGTYPES. Upon return, *ANY_STRUCTURAL_P will be true iff either it was true on entry to this function, or if any of the ARGTYPES are @@ -6961,14 +7081,14 @@ strip_array_types (tree type) canonical argument list is unneeded (i.e., *ANY_STRUCTURAL_P is true) or would not differ from ARGTYPES. */ -static tree -maybe_canonicalize_argtypes(tree argtypes, +static tree +maybe_canonicalize_argtypes(tree argtypes, bool *any_structural_p, bool *any_noncanonical_p) { tree arg; bool any_noncanonical_argtypes_p = false; - + for (arg = argtypes; arg && !(*any_structural_p); arg = TREE_CHAIN (arg)) { if (!TREE_VALUE (arg) || TREE_VALUE (arg) == error_mark_node) @@ -7052,7 +7172,7 @@ build_function_type (tree value_type, tree arg_types) /* Set up the canonical type. */ any_structural_p = TYPE_STRUCTURAL_EQUALITY_P (value_type); any_noncanonical_p = TYPE_CANONICAL (value_type) != value_type; - canon_argtypes = maybe_canonicalize_argtypes (arg_types, + canon_argtypes = maybe_canonicalize_argtypes (arg_types, &any_structural_p, &any_noncanonical_p); if (any_structural_p) @@ -7060,7 +7180,7 @@ build_function_type (tree value_type, tree arg_types) else if (any_noncanonical_p) TYPE_CANONICAL (t) = build_function_type (TYPE_CANONICAL (value_type), canon_argtypes); - + if (!COMPLETE_TYPE_P (t)) layout_type (t); return t; @@ -7126,8 +7246,8 @@ build_function_type_skip_args (tree orig_type, bitmap args_to_skip) return new_type; } -/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP. - +/* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP. + Arguments from DECL_ARGUMENTS list can't be removed now, since they are linked by TREE_CHAIN directly. It is caller responsibility to eliminate them when they are being duplicated (i.e. copy_arguments_for_versioning). */ @@ -7265,7 +7385,7 @@ build_method_type_directly (tree basetype, if (any_structural_p) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (any_noncanonical_p) - TYPE_CANONICAL (t) + TYPE_CANONICAL (t) = build_method_type_directly (TYPE_CANONICAL (basetype), TYPE_CANONICAL (rettype), canon_argtypes); @@ -7321,7 +7441,7 @@ build_offset_type (tree basetype, tree type) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)) != basetype || TYPE_CANONICAL (type) != type) - TYPE_CANONICAL (t) + TYPE_CANONICAL (t) = build_offset_type (TYPE_CANONICAL (TYPE_MAIN_VARIANT (basetype)), TYPE_CANONICAL (type)); } @@ -7358,7 +7478,7 @@ build_complex_type (tree component_type) if (TYPE_STRUCTURAL_EQUALITY_P (component_type)) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (component_type) != component_type) - TYPE_CANONICAL (t) + TYPE_CANONICAL (t) = build_complex_type (TYPE_CANONICAL (component_type)); } @@ -7532,6 +7652,14 @@ get_unwidened (tree op, tree for_type) } } + /* If we finally reach a constant see if it fits in for_type and + in that case convert it. */ + if (for_type + && TREE_CODE (win) == INTEGER_CST + && TREE_TYPE (win) != for_type + && int_fits_type_p (win, for_type)) + win = fold_convert (for_type, win); + return win; } @@ -7787,7 +7915,7 @@ get_type_static_bounds (const_tree type, mpz_t min, mpz_t max) } } - if (!POINTER_TYPE_P (type) && TYPE_MAX_VALUE (type) + if (!POINTER_TYPE_P (type) && TYPE_MAX_VALUE (type) && TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST) mpz_set_double_int (max, tree_to_double_int (TYPE_MAX_VALUE (type)), TYPE_UNSIGNED (type)); @@ -7808,7 +7936,8 @@ 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_CODE (var) == VAR_DECL && ! DECL_EXTERNAL (var)) + || TREE_CODE (var) == PARM_DECL) && ! TREE_STATIC (var)) || TREE_CODE (var) == LABEL_DECL || TREE_CODE (var) == RESULT_DECL)); @@ -8236,7 +8365,7 @@ tree_check_failed (const_tree node, const char *file, while ((code = va_arg (args, int))) { const char *prefix = length ? " or " : "expected "; - + strcpy (tmp + length, prefix); length += strlen (prefix); strcpy (tmp + length, tree_code_name[code]); @@ -8413,9 +8542,9 @@ static const char *ts_enum_names[] = { whether CODE contains the tree structure identified by EN. */ void -tree_contains_struct_check_failed (const_tree node, +tree_contains_struct_check_failed (const_tree node, const enum tree_node_structure_enum en, - const char *file, int line, + const char *file, int line, const char *function) { internal_error @@ -8485,7 +8614,7 @@ make_vector_type (tree innertype, int nunits, enum machine_mode mode) SET_TYPE_STRUCTURAL_EQUALITY (t); else if (TYPE_CANONICAL (innertype) != innertype || mode != VOIDmode) - TYPE_CANONICAL (t) + TYPE_CANONICAL (t) = make_vector_type (TYPE_CANONICAL (innertype), nunits, VOIDmode); layout_type (t); @@ -8625,12 +8754,12 @@ make_or_reuse_accum_type (unsigned size, int unsignedp, int satp) this function to select one of the types as sizetype. */ void -build_common_tree_nodes (bool signed_char, bool signed_sizetype) +build_common_tree_nodes (bool signed_char) { error_mark_node = make_node (ERROR_MARK); TREE_TYPE (error_mark_node) = error_mark_node; - initialize_sizetypes (signed_sizetype); + initialize_sizetypes (); /* Define both `signed char' and `unsigned char'. */ signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); @@ -8745,7 +8874,7 @@ build_common_tree_nodes_2 (int short_double) /* Decimal float types. */ dfloat32_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE; + TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE; layout_type (dfloat32_type_node); SET_TYPE_MODE (dfloat32_type_node, SDmode); dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node); @@ -8757,7 +8886,7 @@ build_common_tree_nodes_2 (int short_double) dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node); dfloat128_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE; + TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE; layout_type (dfloat128_type_node); SET_TYPE_MODE (dfloat128_type_node, TDmode); dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node); @@ -8830,7 +8959,7 @@ build_common_tree_nodes_2 (int short_double) declare the type to be __builtin_va_list. */ if (TREE_CODE (t) != RECORD_TYPE) t = build_variant_type_copy (t); - + va_list_type_node = t; } } @@ -8869,7 +8998,7 @@ local_define_builtin (const char *name, tree type, enum built_in_function code, void build_common_builtin_nodes (void) { - tree tmp, ftype; + tree tmp, tmp2, ftype; if (built_in_decls[BUILT_IN_MEMCPY] == NULL || built_in_decls[BUILT_IN_MEMMOVE] == NULL) @@ -8912,7 +9041,8 @@ build_common_builtin_nodes (void) tmp = tree_cons (NULL_TREE, size_type_node, void_list_node); ftype = build_function_type (ptr_type_node, tmp); local_define_builtin ("__builtin_alloca", ftype, BUILT_IN_ALLOCA, - "alloca", ECF_NOTHROW | ECF_MALLOC); + "alloca", + ECF_MALLOC | (flag_stack_check ? 0 : ECF_NOTHROW)); } tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node); @@ -8974,9 +9104,50 @@ build_common_builtin_nodes (void) local_define_builtin ("__builtin_profile_func_exit", ftype, BUILT_IN_PROFILE_FUNC_EXIT, "profile_func_exit", 0); + /* If there's a possibility that we might use the ARM EABI, build the + alternate __cxa_end_cleanup node used to resume from C++ and Java. */ + if (targetm.arm_eabi_unwinder) + { + ftype = build_function_type (void_type_node, void_list_node); + local_define_builtin ("__builtin_cxa_end_cleanup", ftype, + BUILT_IN_CXA_END_CLEANUP, + "__cxa_end_cleanup", ECF_NORETURN); + } + + tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node); + ftype = build_function_type (void_type_node, tmp); + local_define_builtin ("__builtin_unwind_resume", ftype, + BUILT_IN_UNWIND_RESUME, + (USING_SJLJ_EXCEPTIONS + ? "_Unwind_SjLj_Resume" : "_Unwind_Resume"), + ECF_NORETURN); + + /* The exception object and filter values from the runtime. The argument + must be zero before exception lowering, i.e. from the front end. After + exception lowering, it will be the region number for the exception + landing pad. These functions are PURE instead of CONST to prevent + them from being hoisted past the exception edge that will initialize + its value in the landing pad. */ + tmp = tree_cons (NULL_TREE, integer_type_node, void_list_node); + ftype = build_function_type (ptr_type_node, tmp); + local_define_builtin ("__builtin_eh_pointer", ftype, BUILT_IN_EH_POINTER, + "__builtin_eh_pointer", ECF_PURE | ECF_NOTHROW); + + tmp2 = lang_hooks.types.type_for_mode (targetm.eh_return_filter_mode (), 0); + ftype = build_function_type (tmp2, tmp); + local_define_builtin ("__builtin_eh_filter", ftype, BUILT_IN_EH_FILTER, + "__builtin_eh_filter", ECF_PURE | ECF_NOTHROW); + + tmp = tree_cons (NULL_TREE, integer_type_node, void_list_node); + tmp = tree_cons (NULL_TREE, integer_type_node, tmp); + ftype = build_function_type (void_type_node, tmp); + local_define_builtin ("__builtin_eh_copy_values", ftype, + BUILT_IN_EH_COPY_VALUES, + "__builtin_eh_copy_values", ECF_NOTHROW); + /* Complex multiplication and division. These are handled as builtins rather than optabs because emit_library_call_value doesn't support - complex. Further, we can do slightly better with folding these + complex. Further, we can do slightly better with folding these beasties if the real and complex parts of the arguments are separate. */ { int mode; @@ -9033,7 +9204,7 @@ tree reconstruct_complex_type (tree type, tree bottom) { tree inner, outer; - + if (TREE_CODE (type) == POINTER_TYPE) { inner = reconstruct_complex_type (TREE_TYPE (type), bottom); @@ -9061,8 +9232,8 @@ reconstruct_complex_type (tree type, tree bottom) inner = reconstruct_complex_type (TREE_TYPE (type), bottom); /* The build_method_type_directly() routine prepends 'this' to argument list, so we must compensate by getting rid of it. */ - outer - = build_method_type_directly + outer + = build_method_type_directly (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (type))), inner, TREE_CHAIN (TYPE_ARG_TYPES (type))); @@ -9075,7 +9246,8 @@ reconstruct_complex_type (tree type, tree bottom) else return bottom; - return build_qualified_type (outer, TYPE_QUALS (type)); + return build_type_attribute_qual_variant (outer, TYPE_ATTRIBUTES (type), + TYPE_QUALS (type)); } /* Returns a vector tree node given a mode (integer, vector, or BLKmode) and @@ -9135,16 +9307,6 @@ build_opaque_vector_type (tree innertype, int nunits) } -/* Build RESX_EXPR with given REGION_NUMBER. */ -tree -build_resx (int region_number) -{ - tree t; - t = build1 (RESX_EXPR, void_type_node, - build_int_cst (NULL_TREE, region_number)); - return t; -} - /* Given an initializer INIT, return TRUE if INIT is zero or some aggregate of zeros. Otherwise return FALSE. */ bool @@ -9229,7 +9391,7 @@ build_omp_clause (location_t loc, enum omp_clause_code code) tree_node_counts[(int) omp_clause_kind]++; tree_node_sizes[(int) omp_clause_kind] += size; #endif - + return t; } @@ -9545,11 +9707,19 @@ signed_or_unsigned_type_for (int unsignedp, tree type) { tree t = type; if (POINTER_TYPE_P (type)) - t = size_type_node; + { + /* If the pointer points to the normal address space, use the + size_type_node. Otherwise use an appropriate size for the pointer + based on the named address space it points to. */ + if (!TYPE_ADDR_SPACE (TREE_TYPE (t))) + t = size_type_node; + else + return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp); + } if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp) return t; - + return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp); } @@ -9695,7 +9865,7 @@ operand_equal_for_phi_arg_p (const_tree arg0, const_tree arg1) } /* Returns number of zeros at the end of binary representation of X. - + ??? Use ffs if available? */ tree @@ -10033,7 +10203,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, that are directly gimplified in gimplify_type_sizes in order for the mark/copy-if-shared/unmark machinery of the gimplifier to work with variable-sized types. - + Note that DECLs get walked as part of processing the BIND_EXPR. */ if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL) { @@ -10053,9 +10223,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, return result; /* If this is a record type, also walk the fields. */ - if (TREE_CODE (*type_p) == RECORD_TYPE - || TREE_CODE (*type_p) == UNION_TYPE - || TREE_CODE (*type_p) == QUAL_UNION_TYPE) + if (RECORD_OR_UNION_TYPE_P (*type_p)) { tree field; @@ -10495,6 +10663,9 @@ tree_nop_conversion (const_tree exp) outer_type = TREE_TYPE (exp); inner_type = TREE_TYPE (TREE_OPERAND (exp, 0)); + if (!inner_type) + return false; + /* Use precision rather then machine mode when we can, which gives the correct answer even for submode (bit-field) types. */ if ((INTEGRAL_TYPE_P (outer_type) @@ -10550,5 +10721,20 @@ tree_strip_sign_nop_conversions (tree exp) return exp; } +static GTY(()) tree gcc_eh_personality_decl; + +/* Return the GCC personality function decl. */ + +tree +lhd_gcc_personality (void) +{ + if (!gcc_eh_personality_decl) + gcc_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gcc_personality_sj0" + : "__gcc_personality_v0"); + + return gcc_eh_personality_decl; +} #include "gt-tree.h"