/* Language-independent node constructors for parse phase of GNU compiler.
- Copyright (C) 1987-2016 Free Software Foundation, Inc.
+ Copyright (C) 1987-2017 Free Software Foundation, Inc.
This file is part of GCC.
1, /* OMP_CLAUSE_HINT */
0, /* OMP_CLAUSE_DEFALTMAP */
1, /* OMP_CLAUSE__SIMDUID_ */
+ 0, /* OMP_CLAUSE__SIMT_ */
1, /* OMP_CLAUSE__CILK_FOR_COUNT_ */
0, /* OMP_CLAUSE_INDEPENDENT */
1, /* OMP_CLAUSE_WORKER */
"hint",
"defaultmap",
"_simduid_",
+ "_simt_",
"_Cilk_for_count_",
"independent",
"worker",
{
case TS_TYPED:
case TS_BLOCK:
+ case TS_OPTIMIZATION:
+ case TS_TARGET_OPTION:
MARK_TS_BASE (code);
break;
case TS_VEC:
case TS_BINFO:
case TS_OMP_CLAUSE:
- case TS_OPTIMIZATION:
- case TS_TARGET_OPTION:
MARK_TS_COMMON (code);
break;
{
if (code == FUNCTION_DECL)
{
- SET_DECL_ALIGN (t, FUNCTION_BOUNDARY);
- DECL_MODE (t) = FUNCTION_MODE;
+ SET_DECL_ALIGN (t, FUNCTION_ALIGNMENT (FUNCTION_BOUNDARY));
+ SET_DECL_MODE (t, FUNCTION_MODE);
}
else
SET_DECL_ALIGN (t, 1);
cst_and_fits_in_hwi (const_tree x)
{
return (TREE_CODE (x) == INTEGER_CST
- && TYPE_PRECISION (TREE_TYPE (x)) <= HOST_BITS_PER_WIDE_INT);
+ && (tree_fits_shwi_p (x) || tree_fits_uhwi_p (x)));
}
/* Build a newly constructed VECTOR_CST node of length LEN. */
/* If T needs an assembler name, have one created for it. */
void
-assign_assembler_name_if_neeeded (tree t)
+assign_assembler_name_if_needed (tree t)
{
if (need_assembler_name_p (t))
{
now because free_lang_data_in_decl will invalidate data needed
for mangling. This breaks mangling on interdependent decls. */
FOR_EACH_VEC_ELT (fld.decls, i, t)
- assign_assembler_name_if_neeeded (t);
+ assign_assembler_name_if_needed (t);
/* Traverse every decl found freeing its language data. */
FOR_EACH_VEC_ELT (fld.decls, i, t)
free_lang_data_in_cgraph ();
/* Create gimple variants for common types. */
- ptrdiff_type_node = integer_type_node;
fileptr_type_node = ptr_type_node;
+ const_tm_ptr_type_node = const_ptr_type_node;
/* Reset some langhooks. Do not reset types_compatible_p, it may
still be used indirectly via the get_alias_set langhook. */
TYPE_ADDR_SPACE (type) = DECODE_QUAL_ADDR_SPACE (type_quals);
}
+/* Returns true iff CAND and BASE have equivalent language-specific
+ qualifiers. */
+
+bool
+check_lang_type (const_tree cand, const_tree base)
+{
+ if (lang_hooks.types.type_hash_eq == NULL)
+ return true;
+ /* type_hash_eq currently only applies to these types. */
+ if (TREE_CODE (cand) != FUNCTION_TYPE
+ && TREE_CODE (cand) != METHOD_TYPE)
+ return true;
+ return lang_hooks.types.type_hash_eq (cand, base);
+}
+
/* Returns true iff unqualified CAND and BASE are equivalent. */
bool
check_qualified_type (const_tree cand, const_tree base, int type_quals)
{
return (TYPE_QUALS (cand) == type_quals
- && check_base_type (cand, base));
+ && check_base_type (cand, base)
+ && check_lang_type (cand, base));
}
/* Returns true iff CAND is equivalent to BASE with ALIGN. */
/* Check alignment. */
&& TYPE_ALIGN (cand) == align
&& attribute_list_equal (TYPE_ATTRIBUTES (cand),
- TYPE_ATTRIBUTES (base)));
+ TYPE_ATTRIBUTES (base))
+ && check_lang_type (cand, base));
}
/* This function checks to see if TYPE matches the size one of the built-in
enum tree_code code;
enum tree_code_class tclass;
- if (t == NULL_TREE)
+ if (t == NULL_TREE || t == error_mark_node)
{
hstate.merge_hash (0);
return;
tree
excess_precision_type (tree type)
{
- if (flag_excess_precision != EXCESS_PRECISION_FAST)
+ /* The target can give two different responses to the question of
+ which excess precision mode it would like depending on whether we
+ are in -fexcess-precision=standard or -fexcess-precision=fast. */
+
+ enum excess_precision_type requested_type
+ = (flag_excess_precision == EXCESS_PRECISION_FAST
+ ? EXCESS_PRECISION_TYPE_FAST
+ : EXCESS_PRECISION_TYPE_STANDARD);
+
+ enum flt_eval_method target_flt_eval_method
+ = targetm.c.excess_precision (requested_type);
+
+ /* The target should not ask for unpredictable float evaluation (though
+ it might advertise that implicitly the evaluation is unpredictable,
+ but we don't care about that here, it will have been reported
+ elsewhere). If it does ask for unpredictable evaluation, we have
+ nothing to do here. */
+ gcc_assert (target_flt_eval_method != FLT_EVAL_METHOD_UNPREDICTABLE);
+
+ /* Nothing to do. The target has asked for all types we know about
+ to be computed with their native precision and range. */
+ if (target_flt_eval_method == FLT_EVAL_METHOD_PROMOTE_TO_FLOAT16)
+ return NULL_TREE;
+
+ /* The target will promote this type in a target-dependent way, so excess
+ precision ought to leave it alone. */
+ if (targetm.promoted_type (type) != NULL_TREE)
+ return NULL_TREE;
+
+ machine_mode float16_type_mode = (float16_type_node
+ ? TYPE_MODE (float16_type_node)
+ : VOIDmode);
+ machine_mode float_type_mode = TYPE_MODE (float_type_node);
+ machine_mode double_type_mode = TYPE_MODE (double_type_node);
+
+ switch (TREE_CODE (type))
{
- int flt_eval_method = TARGET_FLT_EVAL_METHOD;
- switch (TREE_CODE (type))
- {
- case REAL_TYPE:
- switch (flt_eval_method)
- {
- case 1:
- if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
- return double_type_node;
- break;
- case 2:
- if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
- || TYPE_MODE (type) == TYPE_MODE (double_type_node))
- return long_double_type_node;
- break;
- default:
- gcc_unreachable ();
- }
- break;
- case COMPLEX_TYPE:
- if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE)
- return NULL_TREE;
- switch (flt_eval_method)
- {
- case 1:
- if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node))
- return complex_double_type_node;
- break;
- case 2:
- if (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (float_type_node)
- || (TYPE_MODE (TREE_TYPE (type))
- == TYPE_MODE (double_type_node)))
- return complex_long_double_type_node;
- break;
- default:
- gcc_unreachable ();
- }
- break;
- default:
- break;
- }
+ case REAL_TYPE:
+ {
+ machine_mode type_mode = TYPE_MODE (type);
+ switch (target_flt_eval_method)
+ {
+ case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT:
+ if (type_mode == float16_type_mode)
+ return float_type_node;
+ break;
+ case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE:
+ if (type_mode == float16_type_mode
+ || type_mode == float_type_mode)
+ return double_type_node;
+ break;
+ case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE:
+ if (type_mode == float16_type_mode
+ || type_mode == float_type_mode
+ || type_mode == double_type_mode)
+ return long_double_type_node;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ break;
+ }
+ case COMPLEX_TYPE:
+ {
+ if (TREE_CODE (TREE_TYPE (type)) != REAL_TYPE)
+ return NULL_TREE;
+ machine_mode type_mode = TYPE_MODE (TREE_TYPE (type));
+ switch (target_flt_eval_method)
+ {
+ case FLT_EVAL_METHOD_PROMOTE_TO_FLOAT:
+ if (type_mode == float16_type_mode)
+ return complex_float_type_node;
+ break;
+ case FLT_EVAL_METHOD_PROMOTE_TO_DOUBLE:
+ if (type_mode == float16_type_mode
+ || type_mode == float_type_mode)
+ return complex_double_type_node;
+ break;
+ case FLT_EVAL_METHOD_PROMOTE_TO_LONG_DOUBLE:
+ if (type_mode == float16_type_mode
+ || type_mode == float_type_mode
+ || type_mode == double_type_mode)
+ return complex_long_double_type_node;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ break;
+ }
+ default:
+ break;
}
+
return NULL_TREE;
}
\f
return win;
}
\f
-/* Returns true if integer constant C has a value that is permissible
- for type TYPE (an INTEGER_TYPE). */
+/* Return true if integer constant C has a value that is permissible
+ for TYPE, an integral type. */
bool
int_fits_type_p (const_tree c, const_tree type)
bool ok_for_low_bound, ok_for_high_bound;
signop sgn_c = TYPE_SIGN (TREE_TYPE (c));
+ /* Non-standard boolean types can have arbitrary precision but various
+ transformations assume that they can only take values 0 and +/-1. */
+ if (TREE_CODE (type) == BOOLEAN_TYPE)
+ return wi::fits_to_boolean_p (c, type);
+
retry:
type_low_bound = TYPE_MIN_VALUE (type);
type_high_bound = TYPE_MAX_VALUE (type);
file = LOCATION_FILE (input_location);
len = strlen (file);
- q = (char *) alloca (9 + 17 + len + 1);
+ q = (char *) alloca (9 + 19 + len + 1);
memcpy (q, file, len + 1);
- snprintf (q + len, 9 + 17 + 1, "_%08X_" HOST_WIDE_INT_PRINT_HEX,
+ snprintf (q + len, 9 + 19 + 1, "_%08X_" HOST_WIDE_INT_PRINT_HEX,
crc32_string (0, name), get_random_seed (false));
p = q;
gcc_unreachable ();
}
+ /* Define what type to use for ptrdiff_t. */
+ if (strcmp (PTRDIFF_TYPE, "int") == 0)
+ ptrdiff_type_node = integer_type_node;
+ else if (strcmp (PTRDIFF_TYPE, "long int") == 0)
+ ptrdiff_type_node = long_integer_type_node;
+ else if (strcmp (PTRDIFF_TYPE, "long long int") == 0)
+ ptrdiff_type_node = long_long_integer_type_node;
+ else if (strcmp (PTRDIFF_TYPE, "short int") == 0)
+ ptrdiff_type_node = short_integer_type_node;
+ else
+ {
+ ptrdiff_type_node = NULL_TREE;
+ for (int i = 0; i < NUM_INT_N_ENTS; i++)
+ if (int_n_enabled_p[i])
+ {
+ char name[50];
+ sprintf (name, "__int%d", int_n_data[i].bitsize);
+ if (strcmp (name, PTRDIFF_TYPE) == 0)
+ ptrdiff_type_node = int_n_trees[i].signed_type;
+ }
+ if (ptrdiff_type_node == NULL_TREE)
+ gcc_unreachable ();
+ }
+
/* Fill in the rest of the sized types. Reuse existing type nodes
when possible. */
intQI_type_node = make_or_reuse_type (GET_MODE_BITSIZE (QImode), 0);
const_ptr_type_node
= build_pointer_type (build_type_variant (void_type_node, 1, 0));
fileptr_type_node = ptr_type_node;
+ const_tm_ptr_type_node = const_ptr_type_node;
pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);
/* Decimal float types. */
dfloat32_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
- layout_type (dfloat32_type_node);
SET_TYPE_MODE (dfloat32_type_node, SDmode);
+ layout_type (dfloat32_type_node);
dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
dfloat64_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
- layout_type (dfloat64_type_node);
SET_TYPE_MODE (dfloat64_type_node, DDmode);
+ layout_type (dfloat64_type_node);
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;
- layout_type (dfloat128_type_node);
SET_TYPE_MODE (dfloat128_type_node, TDmode);
+ layout_type (dfloat128_type_node);
dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
complex_integer_type_node = build_complex_type (integer_type_node, true);
BUILT_IN_INIT_HEAP_TRAMPOLINE,
"__builtin_init_heap_trampoline",
ECF_NOTHROW | ECF_LEAF);
+ local_define_builtin ("__builtin_init_descriptor", ftype,
+ BUILT_IN_INIT_DESCRIPTOR,
+ "__builtin_init_descriptor", ECF_NOTHROW | ECF_LEAF);
ftype = build_function_type_list (ptr_type_node, ptr_type_node, NULL_TREE);
local_define_builtin ("__builtin_adjust_trampoline", ftype,
BUILT_IN_ADJUST_TRAMPOLINE,
"__builtin_adjust_trampoline",
ECF_CONST | ECF_NOTHROW);
+ local_define_builtin ("__builtin_adjust_descriptor", ftype,
+ BUILT_IN_ADJUST_DESCRIPTOR,
+ "__builtin_adjust_descriptor",
+ ECF_CONST | ECF_NOTHROW);
ftype = build_function_type_list (void_type_node,
ptr_type_node, ptr_type_node, NULL_TREE);
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
case OMP_CLAUSE_TILE:
+ case OMP_CLAUSE__SIMT_:
WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
case OMP_CLAUSE_LASTPRIVATE:
- aggregates may have new TYPE_FIELDS list that list variants of
the main variant TYPE_FIELDS.
- vector types may differ by TYPE_VECTOR_OPAQUE
- - TYPE_METHODS is always NULL for vairant types and maintained for
+ - TYPE_METHODS is always NULL for variant types and maintained for
main variant only.
*/
verify_variant_match (TYPE_SIZE);
if (TREE_CODE (TYPE_SIZE_UNIT (t)) != PLACEHOLDER_EXPR
&& TREE_CODE (TYPE_SIZE_UNIT (tv)) != PLACEHOLDER_EXPR
- && TYPE_SIZE_UNIT (t) != TYPE_SIZE_UNIT (tv)
- /* FIXME: ideally we should compare pointer equality, but java FE
- produce variants where size is INTEGER_CST of different type (int
- wrt size_type) during libjava biuld. */
- && !operand_equal_p (TYPE_SIZE_UNIT (t), TYPE_SIZE_UNIT (tv), 0))
+ && TYPE_SIZE_UNIT (t) != TYPE_SIZE_UNIT (tv))
{
+ gcc_assert (!operand_equal_p (TYPE_SIZE_UNIT (t),
+ TYPE_SIZE_UNIT (tv), 0));
error ("type variant has different TYPE_SIZE_UNIT");
debug_tree (tv);
error ("type variant's TYPE_SIZE_UNIT");
if (type_with_alias_set_p (t)
&& !gimple_canonical_types_compatible_p (t, tv, false))
{
- error ("type is not compatible with its vairant");
+ error ("type is not compatible with its variant");
debug_tree (tv);
error ("type variant's TREE_TYPE");
debug_tree (TREE_TYPE (tv));
f1 || f2;
f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
{
- /* Skip non-fields. */
- while (f1 && TREE_CODE (f1) != FIELD_DECL)
+ /* Skip non-fields and zero-sized fields. */
+ while (f1 && (TREE_CODE (f1) != FIELD_DECL
+ || (DECL_SIZE (f1)
+ && integer_zerop (DECL_SIZE (f1)))))
f1 = TREE_CHAIN (f1);
- while (f2 && TREE_CODE (f2) != FIELD_DECL)
+ while (f2 && (TREE_CODE (f2) != FIELD_DECL
+ || (DECL_SIZE (f2)
+ && integer_zerop (DECL_SIZE (f2)))))
f2 = TREE_CHAIN (f2);
if (!f1 || !f2)
break;
return internal_fn_name (as_internal_fn (fn));
}
+/* Return a bitmap with a bit set corresponding to each argument in
+ a function call type FNTYPE declared with attribute nonnull,
+ or null if none of the function's argument are nonnull. The caller
+ must free the bitmap. */
+
+bitmap
+get_nonnull_args (const_tree fntype)
+{
+ if (fntype == NULL_TREE)
+ return NULL;
+
+ tree attrs = TYPE_ATTRIBUTES (fntype);
+ if (!attrs)
+ return NULL;
+
+ bitmap argmap = NULL;
+
+ /* A function declaration can specify multiple attribute nonnull,
+ each with zero or more arguments. The loop below creates a bitmap
+ representing a union of all the arguments. An empty (but non-null)
+ bitmap means that all arguments have been declaraed nonnull. */
+ for ( ; attrs; attrs = TREE_CHAIN (attrs))
+ {
+ attrs = lookup_attribute ("nonnull", attrs);
+ if (!attrs)
+ break;
+
+ if (!argmap)
+ argmap = BITMAP_ALLOC (NULL);
+
+ if (!TREE_VALUE (attrs))
+ {
+ /* Clear the bitmap in case a previous attribute nonnull
+ set it and this one overrides it for all arguments. */
+ bitmap_clear (argmap);
+ return argmap;
+ }
+
+ /* Iterate over the indices of the format arguments declared nonnull
+ and set a bit for each. */
+ for (tree idx = TREE_VALUE (attrs); idx; idx = TREE_CHAIN (idx))
+ {
+ unsigned int val = TREE_INT_CST_LOW (TREE_VALUE (idx)) - 1;
+ bitmap_set_bit (argmap, val);
+ }
+ }
+
+ return argmap;
+}
+
#if CHECKING_P
namespace selftest {