summaryrefslogtreecommitdiff
path: root/gcc/tree.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree.c')
-rw-r--r--gcc/tree.c363
1 files changed, 240 insertions, 123 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 315df903b30..f3970dd3a55 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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. */
@@ -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:
@@ -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);
}
@@ -872,7 +880,10 @@ 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++;
if (TREE_CODE (t) == LABEL_DECL)
LABEL_DECL_UID (t) = -1;
@@ -948,7 +959,10 @@ copy_node_stat (tree node MEM_STAT_DECL)
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 ((TREE_CODE (node) == PARM_DECL || TREE_CODE (node) == VAR_DECL)
&& DECL_HAS_VALUE_EXPR_P (node))
{
@@ -1670,8 +1684,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 = int_or_pointer_precision (TREE_TYPE (expr));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
@@ -1735,9 +1748,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 = int_or_pointer_precision (TREE_TYPE (expr));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
@@ -1773,9 +1784,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 = int_or_pointer_precision (TREE_TYPE (expr));
high = TREE_INT_CST_HIGH (expr);
low = TREE_INT_CST_LOW (expr);
@@ -3939,9 +3948,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 : _("<built-in>");
xloc.line = 0;
xloc.column = 0;
xloc.sysp = 0;
@@ -4130,6 +4139,31 @@ 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_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;
+
+ 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
@@ -4137,11 +4171,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);
@@ -4179,9 +4208,7 @@ 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;
@@ -4215,30 +4242,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
{
@@ -4276,19 +4280,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_node_for_decl (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;
}
@@ -4340,9 +4347,6 @@ 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)
@@ -4388,6 +4392,10 @@ free_lang_data_in_decl (tree decl)
&& DECL_FIELD_OFFSET (decl)
&& TREE_CODE (DECL_FIELD_OFFSET (decl)) != INTEGER_CST)
DECL_FIELD_OFFSET (decl) = NULL_TREE;
+
+ /* DECL_FCONTEXT is only used for debug info generation. */
+ if (TREE_CODE (decl) == FIELD_DECL)
+ DECL_FCONTEXT (decl) = NULL_TREE;
}
else if (TREE_CODE (decl) == FUNCTION_DECL)
{
@@ -4438,7 +4446,8 @@ 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)
@@ -4522,15 +4531,21 @@ add_tree_to_fld_list (tree t, struct free_lang_data_d *fld)
gcc_unreachable ();
}
-#define PUSH(t) \
- if (t && !pointer_set_contains (fld->pset, t)) \
- VEC_safe_push (tree, heap, fld->worklist, (t))
+/* 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;
@@ -4538,45 +4553,59 @@ find_decls_types_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *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);
- PUSH (DECL_NAME (t));
- PUSH (DECL_CONTEXT (t));
- PUSH (DECL_SIZE (t));
- PUSH (DECL_SIZE_UNIT (t));
- PUSH (DECL_INITIAL(t));
- PUSH (DECL_ATTRIBUTES (t));
- PUSH (DECL_ABSTRACT_ORIGIN (t));
+ 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)
{
- PUSH (DECL_ARGUMENTS (t));
- PUSH (DECL_RESULT (t));
+ fld_worklist_push (DECL_ARGUMENTS (t), fld);
+ fld_worklist_push (DECL_RESULT (t), fld);
}
else if (TREE_CODE (t) == TYPE_DECL)
{
- PUSH (DECL_ARGUMENT_FLD (t));
- PUSH (DECL_VINDEX (t));
+ fld_worklist_push (DECL_ARGUMENT_FLD (t), fld);
+ fld_worklist_push (DECL_VINDEX (t), fld);
}
else if (TREE_CODE (t) == FIELD_DECL)
{
- PUSH (DECL_FIELD_OFFSET (t));
- PUSH (DECL_BIT_FIELD_TYPE (t));
- PUSH (DECL_QUALIFIER (t));
- PUSH (DECL_FIELD_BIT_OFFSET (t));
- PUSH (DECL_FCONTEXT (t));
+ 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)
{
- PUSH (DECL_SECTION_NAME (t));
- PUSH (DECL_COMDAT_GROUP (t));
+ fld_worklist_push (DECL_SECTION_NAME (t), fld);
+ fld_worklist_push (DECL_COMDAT_GROUP (t), fld);
}
- PUSH (TREE_CHAIN (t));
+ if (TREE_CODE (t) != FIELD_DECL)
+ fld_worklist_push (TREE_CHAIN (t), fld);
*ws = 0;
}
else if (TYPE_P (t))
@@ -4585,40 +4614,63 @@ 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);
- PUSH (TYPE_CACHED_VALUES (t));
- PUSH (TYPE_SIZE (t));
- PUSH (TYPE_SIZE_UNIT (t));
- PUSH (TYPE_ATTRIBUTES (t));
- PUSH (TYPE_POINTER_TO (t));
- PUSH (TYPE_REFERENCE_TO (t));
- PUSH (TYPE_NAME (t));
- PUSH (TYPE_MINVAL (t));
- PUSH (TYPE_MAXVAL (t));
- PUSH (TYPE_MAIN_VARIANT (t));
- PUSH (TYPE_NEXT_VARIANT (t));
- PUSH (TYPE_CONTEXT (t));
- PUSH (TYPE_CANONICAL (t));
-
- if (RECORD_OR_UNION_TYPE_P (t)
- && TYPE_BINFO (t))
+ 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)
- PUSH (TREE_TYPE (tem));
+ 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);
+ }
}
- PUSH (TREE_CHAIN (t));
+ fld_worklist_push (TREE_CHAIN (t), fld);
*ws = 0;
}
- PUSH (TREE_TYPE (t));
+ fld_worklist_push (TREE_TYPE (t), fld);
return NULL_TREE;
}
-#undef PUSH
/* Find decls and types in T. */
@@ -4867,6 +4919,20 @@ free_lang_data_in_cgraph (void)
static unsigned
free_lang_data (void)
{
+ unsigned i;
+
+ /* 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]);
+
+ /* FIXME. Remove after save_debug_info is working. */
+ if (!(flag_generate_lto
+ || (!in_lto_p
+ && !flag_gtoggle && debug_info_level <= DINFO_LEVEL_TERSE)))
+ return 0;
+
/* Traverse the IL resetting language specific information for
operands, expressions, etc. */
free_lang_data_in_cgraph ();
@@ -4894,9 +4960,9 @@ free_lang_data (void)
else
signed_char_type_node = char_type_node;
- /* Reset some langhooks. */
+ /* 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;
@@ -4907,17 +4973,14 @@ free_lang_data (void)
diagnostic_finalizer (global_dc) = default_diagnostic_finalizer;
diagnostic_format_decoder (global_dc) = default_tree_printer;
- return 0;
-}
-
+ /* FIXME. We remove sufficient language data that the debug
+ info writer gets completely confused. Disable debug information
+ for now. */
+ debug_info_level = DINFO_LEVEL_NONE;
+ write_symbols = NO_DEBUG;
+ debug_hooks = &do_nothing_debug_hooks;
-/* 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;
+ return 0;
}
@@ -4926,7 +4989,7 @@ struct simple_ipa_opt_pass pass_ipa_free_lang_data =
{
SIMPLE_IPA_PASS,
NULL, /* name */
- gate_free_lang_data, /* gate */
+ NULL, /* gate */
free_lang_data, /* execute */
NULL, /* sub */
NULL, /* next */
@@ -5353,6 +5416,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. */
@@ -6674,7 +6738,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. */
@@ -6738,7 +6805,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
@@ -6932,6 +7002,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
@@ -8938,7 +9009,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);
@@ -9602,7 +9674,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
+ {
+ int prec = int_or_pointer_precision (t);
+ return lang_hooks.types.type_for_size (prec, unsignedp);
+ }
+ }
if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp)
return t;
@@ -10110,9 +10194,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;
@@ -10478,6 +10560,41 @@ build_target_option_node (void)
return t;
}
+/* Return the size in bits of an integer or pointer type. TYPE_PRECISION
+ contains the bits, but in the past it was not set in some cases and there
+ was special purpose code that checked for POINTER_TYPE_P or OFFSET_TYPE, so
+ check that it is consitant when assertion checking is used. */
+
+unsigned int
+int_or_pointer_precision (const_tree type)
+{
+#if ENABLE_ASSERT_CHECKING
+ unsigned int prec;
+
+ if (POINTER_TYPE_P (type))
+ {
+ addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (type));
+ prec = GET_MODE_BITSIZE (targetm.addr_space.pointer_mode (as));
+ gcc_assert (prec == TYPE_PRECISION (type));
+ }
+ else if (TREE_CODE (type) == OFFSET_TYPE)
+ {
+ prec = POINTER_SIZE;
+ gcc_assert (prec == TYPE_PRECISION (type));
+ }
+ else
+ {
+ prec = TYPE_PRECISION (type);
+ gcc_assert (prec != 0);
+ }
+
+ return prec;
+
+#else
+ return TYPE_PRECISION (type);
+#endif
+}
+
/* Determine the "ultimate origin" of a block. The block may be an inlined
instance of an inlined instance of a block which is local to an inline
function, so we have to trace all of the way back through the origin chain