/* Definitions for the ubiquitous 'tree' type for GNU compilers.
- Copyright (C) 1989-2015 Free Software Foundation, Inc.
+ Copyright (C) 1989-2018 Free Software Foundation, Inc.
This file is part of GCC.
/* Macros for initializing `tree_contains_struct'. */
#define MARK_TS_BASE(C) \
- do { \
- tree_contains_struct[C][TS_BASE] = 1; \
- } while (0)
+ (tree_contains_struct[C][TS_BASE] = true)
#define MARK_TS_TYPED(C) \
- do { \
- MARK_TS_BASE (C); \
- tree_contains_struct[C][TS_TYPED] = 1; \
- } while (0)
+ (MARK_TS_BASE (C), \
+ tree_contains_struct[C][TS_TYPED] = true)
#define MARK_TS_COMMON(C) \
- do { \
- MARK_TS_TYPED (C); \
- tree_contains_struct[C][TS_COMMON] = 1; \
- } while (0)
+ (MARK_TS_TYPED (C), \
+ tree_contains_struct[C][TS_COMMON] = true)
#define MARK_TS_TYPE_COMMON(C) \
- do { \
- MARK_TS_COMMON (C); \
- tree_contains_struct[C][TS_TYPE_COMMON] = 1; \
- } while (0)
+ (MARK_TS_COMMON (C), \
+ tree_contains_struct[C][TS_TYPE_COMMON] = true)
#define MARK_TS_TYPE_WITH_LANG_SPECIFIC(C) \
- do { \
- MARK_TS_TYPE_COMMON (C); \
- tree_contains_struct[C][TS_TYPE_WITH_LANG_SPECIFIC] = 1; \
- } while (0)
+ (MARK_TS_TYPE_COMMON (C), \
+ tree_contains_struct[C][TS_TYPE_WITH_LANG_SPECIFIC] = true)
#define MARK_TS_DECL_MINIMAL(C) \
- do { \
- MARK_TS_COMMON (C); \
- tree_contains_struct[C][TS_DECL_MINIMAL] = 1; \
- } while (0)
+ (MARK_TS_COMMON (C), \
+ tree_contains_struct[C][TS_DECL_MINIMAL] = true)
#define MARK_TS_DECL_COMMON(C) \
- do { \
- MARK_TS_DECL_MINIMAL (C); \
- tree_contains_struct[C][TS_DECL_COMMON] = 1; \
- } while (0)
+ (MARK_TS_DECL_MINIMAL (C), \
+ tree_contains_struct[C][TS_DECL_COMMON] = true)
#define MARK_TS_DECL_WRTL(C) \
- do { \
- MARK_TS_DECL_COMMON (C); \
- tree_contains_struct[C][TS_DECL_WRTL] = 1; \
- } while (0)
+ (MARK_TS_DECL_COMMON (C), \
+ tree_contains_struct[C][TS_DECL_WRTL] = true)
#define MARK_TS_DECL_WITH_VIS(C) \
- do { \
- MARK_TS_DECL_WRTL (C); \
- tree_contains_struct[C][TS_DECL_WITH_VIS] = 1; \
- } while (0)
+ (MARK_TS_DECL_WRTL (C), \
+ tree_contains_struct[C][TS_DECL_WITH_VIS] = true)
#define MARK_TS_DECL_NON_COMMON(C) \
- do { \
- MARK_TS_DECL_WITH_VIS (C); \
- tree_contains_struct[C][TS_DECL_NON_COMMON] = 1; \
- } while (0)
-
+ (MARK_TS_DECL_WITH_VIS (C), \
+ tree_contains_struct[C][TS_DECL_NON_COMMON] = true)
/* Returns the string representing CLASS. */
/* Helper macros for math builtins. */
-#define BUILTIN_EXP10_P(FN) \
- ((FN) == BUILT_IN_EXP10 || (FN) == BUILT_IN_EXP10F || (FN) == BUILT_IN_EXP10L \
- || (FN) == BUILT_IN_POW10 || (FN) == BUILT_IN_POW10F || (FN) == BUILT_IN_POW10L)
-
-#define BUILTIN_EXPONENT_P(FN) (BUILTIN_EXP10_P (FN) \
- || (FN) == BUILT_IN_EXP || (FN) == BUILT_IN_EXPF || (FN) == BUILT_IN_EXPL \
- || (FN) == BUILT_IN_EXP2 || (FN) == BUILT_IN_EXP2F || (FN) == BUILT_IN_EXP2L)
-
-#define BUILTIN_SQRT_P(FN) \
- ((FN) == BUILT_IN_SQRT || (FN) == BUILT_IN_SQRTF || (FN) == BUILT_IN_SQRTL)
-
-#define BUILTIN_CBRT_P(FN) \
- ((FN) == BUILT_IN_CBRT || (FN) == BUILT_IN_CBRTF || (FN) == BUILT_IN_CBRTL)
-
-#define BUILTIN_ROOT_P(FN) (BUILTIN_SQRT_P (FN) || BUILTIN_CBRT_P (FN))
-
#define CASE_FLT_FN(FN) case FN: case FN##F: case FN##L
+#define CASE_FLT_FN_FLOATN_NX(FN) \
+ case FN##F16: case FN##F32: case FN##F64: case FN##F128: \
+ case FN##F32X: case FN##F64X: case FN##F128X
#define CASE_FLT_FN_REENT(FN) case FN##_R: case FN##F_R: case FN##L_R
#define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL: case FN##IMAX
extern void tree_contains_struct_check_failed (const_tree,
const enum tree_node_structure_enum,
const char *, int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_check_failed (const_tree, const char *, int, const char *,
- ...) ATTRIBUTE_NORETURN;
+ ...) ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_not_check_failed (const_tree, const char *, int, const char *,
- ...) ATTRIBUTE_NORETURN;
+ ...) ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_class_check_failed (const_tree, const enum tree_code_class,
const char *, int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_range_check_failed (const_tree, const char *, int,
const char *, enum tree_code,
enum tree_code)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_not_class_check_failed (const_tree,
const enum tree_code_class,
const char *, int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_int_cst_elt_check_failed (int, int, const char *,
int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_vec_elt_check_failed (int, int, const char *,
int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void phi_node_elt_check_failed (int, int, const char *,
int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void tree_operand_check_failed (int, const_tree,
const char *, int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void omp_clause_check_failed (const_tree, const char *, int,
const char *, enum omp_clause_code)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void omp_clause_operand_check_failed (int, const_tree, const char *,
int, const char *)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
extern void omp_clause_range_check_failed (const_tree, const char *, int,
const char *, enum omp_clause_code,
enum omp_clause_code)
- ATTRIBUTE_NORETURN;
+ ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
#else /* not ENABLE_TREE_CHECKING, or not gcc */
#define CALL_EXPR_TAILCALL(NODE) \
(CALL_EXPR_CHECK (NODE)->base.addressable_flag)
+/* Set on a CALL_EXPR if the call has been marked as requiring tail call
+ optimization for correctness. */
+#define CALL_EXPR_MUST_TAIL_CALL(NODE) \
+ (CALL_EXPR_CHECK (NODE)->base.static_flag)
+
/* Used as a temporary field on a CASE_LABEL_EXPR to indicate that the
CASE_LOW operand has been processed. */
#define CASE_LOW_SEEN(NODE) \
emitted. */
#define TREE_NO_WARNING(NODE) ((NODE)->base.nowarning_flag)
+/* Nonzero if we should warn about the change in empty class parameter
+ passing ABI in this TU. */
+#define TRANSLATION_UNIT_WARN_EMPTY_P(NODE) \
+ (TRANSLATION_UNIT_DECL_CHECK (NODE)->decl_common.decl_flag_0)
+
+/* Nonzero if this type is "empty" according to the particular psABI. */
+#define TYPE_EMPTY_P(NODE) (TYPE_CHECK (NODE)->type_common.empty_flag)
+
/* Used to indicate that this TYPE represents a compiler-generated entity. */
#define TYPE_ARTIFICIAL(NODE) (TYPE_CHECK (NODE)->base.nowarning_flag)
computed gotos. */
#define FORCED_LABEL(NODE) (LABEL_DECL_CHECK (NODE)->base.side_effects_flag)
+/* Whether a case or a user-defined label is allowed to fall through to.
+ This is used to implement -Wimplicit-fallthrough. */
+#define FALLTHROUGH_LABEL_P(NODE) \
+ (LABEL_DECL_CHECK (NODE)->base.private_flag)
+
+/* Set on the artificial label created for break; stmt from a switch.
+ This is used to implement -Wimplicit-fallthrough. */
+#define SWITCH_BREAK_LABEL_P(NODE) \
+ (LABEL_DECL_CHECK (NODE)->base.protected_flag)
+
/* Nonzero means this expression is volatile in the C sense:
its address should be of type `volatile WHATEVER *'.
In other words, the declared item is volatile qualified.
caller decide whether a warning is appropriate or not. */
#define TYPE_OVERFLOW_UNDEFINED(TYPE) \
(!ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag \
- && !flag_wrapv && !flag_trapv && flag_strict_overflow)
+ && !flag_wrapv && !flag_trapv)
/* True if overflow for the given integral type should issue a
trap. */
&& !TYPE_OVERFLOW_WRAPS (TYPE) \
&& (flag_sanitize & SANITIZE_SI_OVERFLOW))
-/* True if pointer types have undefined overflow. */
-#define POINTER_TYPE_OVERFLOW_UNDEFINED (flag_strict_overflow)
-
/* Nonzero in a VAR_DECL or STRING_CST means assembler code has been written.
Nonzero in a FUNCTION_DECL means that the function has been compiled.
This is interesting in an inline function, since it might not need
#define CALL_EXPR_RETURN_SLOT_OPT(NODE) \
(CALL_EXPR_CHECK (NODE)->base.private_flag)
-/* Cilk keywords accessors. */
-#define CILK_SPAWN_FN(NODE) TREE_OPERAND (CILK_SPAWN_STMT_CHECK (NODE), 0)
-
/* In a RESULT_DECL, PARM_DECL and VAR_DECL, means that it is
passed by invisible reference (and the TREE_TYPE is a pointer to the true
type). */
/* In a CALL_EXPR, means call was instrumented by Pointer Bounds Checker. */
#define CALL_WITH_BOUNDS_P(NODE) (CALL_EXPR_CHECK (NODE)->base.deprecated_flag)
-/* In a type, nonzero means that all objects of the type are guaranteed by the
- language or front-end to be properly aligned, so we can indicate that a MEM
- of this type is aligned at least to the alignment of the type, even if it
- doesn't appear that it is. We see this, for example, in object-oriented
- languages where a tag field may show this is an object of a more-aligned
- variant of the more generic type.
-
- In an SSA_NAME node, nonzero if the SSA_NAME node is on the SSA_NAME
- freelist. */
-#define TYPE_ALIGN_OK(NODE) (TYPE_CHECK (NODE)->base.nothrow_flag)
-
/* Used in classes in C++. */
#define TREE_PRIVATE(NODE) ((NODE)->base.private_flag)
/* Used in classes in C++. */
#define REF_REVERSE_STORAGE_ORDER(NODE) \
(TREE_CHECK2 (NODE, BIT_FIELD_REF, MEM_REF)->base.default_def_flag)
+ /* In an ADDR_EXPR, indicates that this is a pointer to nested function
+ represented by a descriptor instead of a trampoline. */
+#define FUNC_ADDR_BY_DESCRIPTOR(NODE) \
+ (TREE_CHECK (NODE, ADDR_EXPR)->base.default_def_flag)
+
+/* In a CALL_EXPR, indicates that this is an indirect call for which
+ pointers to nested function are descriptors instead of trampolines. */
+#define CALL_EXPR_BY_DESCRIPTOR(NODE) \
+ (TREE_CHECK (NODE, CALL_EXPR)->base.default_def_flag)
+
/* These flags are available for each language front end to use internally. */
#define TREE_LANG_FLAG_0(NODE) \
(TREE_NOT_CHECK2 (NODE, TREE_VEC, SSA_NAME)->base.u.bits.lang_flag_0)
#define TREE_INT_CST_LOW(NODE) \
((unsigned HOST_WIDE_INT) TREE_INT_CST_ELT (NODE, 0))
+/* Return true if NODE is a POLY_INT_CST. This is only ever true on
+ targets with variable-sized modes. */
+#define POLY_INT_CST_P(NODE) \
+ (NUM_POLY_INT_COEFFS > 1 && TREE_CODE (NODE) == POLY_INT_CST)
+
+/* In a POLY_INT_CST node. */
+#define POLY_INT_CST_COEFF(NODE, I) \
+ (POLY_INT_CST_CHECK (NODE)->poly_int_cst.coeffs[I])
+
#define TREE_REAL_CST_PTR(NODE) (REAL_CST_CHECK (NODE)->real_cst.real_cst_ptr)
#define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE))
#define TREE_REALPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.real)
#define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
-/* In a VECTOR_CST node. */
+/* In a VECTOR_CST node. See generic.texi for details. */
#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE)))
-#define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
-#define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])
+#define VECTOR_CST_ELT(NODE,IDX) vector_cst_elt (NODE, IDX)
+
+#define VECTOR_CST_LOG2_NPATTERNS(NODE) \
+ (VECTOR_CST_CHECK (NODE)->base.u.vector_cst.log2_npatterns)
+#define VECTOR_CST_NPATTERNS(NODE) \
+ (1U << VECTOR_CST_LOG2_NPATTERNS (NODE))
+#define VECTOR_CST_NELTS_PER_PATTERN(NODE) \
+ (VECTOR_CST_CHECK (NODE)->base.u.vector_cst.nelts_per_pattern)
+#define VECTOR_CST_DUPLICATE_P(NODE) \
+ (VECTOR_CST_NELTS_PER_PATTERN (NODE) == 1)
+#define VECTOR_CST_STEPPED_P(NODE) \
+ (VECTOR_CST_NELTS_PER_PATTERN (NODE) == 3)
+#define VECTOR_CST_ENCODED_ELTS(NODE) \
+ (VECTOR_CST_CHECK (NODE)->vector.elts)
+#define VECTOR_CST_ENCODED_ELT(NODE, ELT) \
+ (VECTOR_CST_CHECK (NODE)->vector.elts[ELT])
/* Define fields and accessors for some special-purpose tree nodes. */
#define VL_EXP_OPERAND_LENGTH(NODE) \
((int)TREE_INT_CST_LOW (VL_EXP_CHECK (NODE)->exp.operands[0]))
+/* Nonzero if gimple_debug_nonbind_marker_p() may possibly hold. */
+#define MAY_HAVE_DEBUG_MARKER_STMTS debug_nonbind_markers_p
+/* Nonzero if gimple_debug_bind_p() (and thus
+ gimple_debug_source_bind_p()) may possibly hold. */
+#define MAY_HAVE_DEBUG_BIND_STMTS flag_var_tracking_assignments
/* Nonzero if is_gimple_debug() may possibly hold. */
-#define MAY_HAVE_DEBUG_STMTS (flag_var_tracking_assignments)
+#define MAY_HAVE_DEBUG_STMTS \
+ (MAY_HAVE_DEBUG_MARKER_STMTS || MAY_HAVE_DEBUG_BIND_STMTS)
/* In a LOOP_EXPR node. */
#define LOOP_EXPR_BODY(NODE) TREE_OPERAND_CHECK_CODE (NODE, LOOP_EXPR, 0)
#define COMPOUND_LITERAL_EXPR_DECL(NODE) \
DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_EXPR (NODE))
-/* SWITCH_EXPR accessors. These give access to the condition, body and
- original condition type (before any compiler conversions)
- of the switch statement, respectively. */
+/* SWITCH_EXPR accessors. These give access to the condition and body. */
#define SWITCH_COND(NODE) TREE_OPERAND (SWITCH_EXPR_CHECK (NODE), 0)
#define SWITCH_BODY(NODE) TREE_OPERAND (SWITCH_EXPR_CHECK (NODE), 1)
-#define SWITCH_LABELS(NODE) TREE_OPERAND (SWITCH_EXPR_CHECK (NODE), 2)
+/* True if there are case labels for all possible values of SWITCH_COND, either
+ because there is a default: case label or because the case label ranges cover
+ all values. */
+#define SWITCH_ALL_CASES_P(NODE) (SWITCH_EXPR_CHECK (NODE)->base.private_flag)
/* CASE_LABEL_EXPR accessors. These give access to the high and low values
of a case label, respectively. */
/* GOTO_EXPR accessor. This gives access to the label associated with
a goto statement. */
-#define GOTO_DESTINATION(NODE) TREE_OPERAND ((NODE), 0)
+#define GOTO_DESTINATION(NODE) TREE_OPERAND (GOTO_EXPR_CHECK (NODE), 0)
/* ASM_EXPR accessors. ASM_STRING returns a STRING_CST for the
instruction (e.g., "mov x, y"). ASM_OUTPUTS, ASM_INPUTS, and
#define COND_EXPR_ELSE(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 2))
/* Accessors for the chains of recurrences. */
-#define CHREC_VAR(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 0)
-#define CHREC_LEFT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 1)
-#define CHREC_RIGHT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 2)
-#define CHREC_VARIABLE(NODE) TREE_INT_CST_LOW (CHREC_VAR (NODE))
+#define CHREC_LEFT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 0)
+#define CHREC_RIGHT(NODE) TREE_OPERAND (POLYNOMIAL_CHREC_CHECK (NODE), 1)
+#define CHREC_VARIABLE(NODE) POLYNOMIAL_CHREC_CHECK (NODE)->base.u.chrec_var
/* LABEL_EXPR accessor. This gives access to the label associated with
the given label expression. */
#define OMP_CLAUSE_PRIVATE_TASKLOOP_IV(NODE) \
TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PRIVATE))
+/* True on a FIRSTPRIVATE clause if it has been added implicitly. */
+#define OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FIRSTPRIVATE)->base.public_flag)
+
/* True on a LASTPRIVATE clause if a FIRSTPRIVATE clause for the same
decl is present in the chain. */
#define OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE(NODE) \
#define OMP_CLAUSE_SHARED_FIRSTPRIVATE(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SHARED)->base.public_flag)
+/* True on a SHARED clause if a scalar is not modified in the body and
+ thus could be optimized as firstprivate. */
+#define OMP_CLAUSE_SHARED_READONLY(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SHARED))
+
#define OMP_CLAUSE_IF_MODIFIER(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_IF)->omp_clause.subcode.if_modifier)
treatment if OMP_CLAUSE_SIZE is zero. */
#define OMP_CLAUSE_MAP_MAYBE_ZERO_LENGTH_ARRAY_SECTION(NODE) \
TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP))
+/* Nonzero if this map clause is for an ACC parallel reduction variable. */
+#define OMP_CLAUSE_MAP_IN_REDUCTION(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP))
#define OMP_CLAUSE_PROC_BIND_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PROC_BIND)->omp_clause.subcode.proc_bind_kind)
#define OMP_CLAUSE_TILE_LIST(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_TILE), 0)
+#define OMP_CLAUSE_TILE_ITERVAR(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_TILE), 1)
+#define OMP_CLAUSE_TILE_COUNT(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_TILE), 2)
+
+#define OMP_CLAUSE__GRIDDIM__DIMENSION(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__GRIDDIM_)\
+ ->omp_clause.subcode.dimension)
+#define OMP_CLAUSE__GRIDDIM__SIZE(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__GRIDDIM_), 0)
+#define OMP_CLAUSE__GRIDDIM__GROUP(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__GRIDDIM_), 1)
/* SSA_NAME accessors. */
+/* Whether SSA_NAME NODE is a virtual operand. This simply caches the
+ information in the underlying SSA_NAME_VAR for efficiency. */
+#define SSA_NAME_IS_VIRTUAL_OPERAND(NODE) \
+ SSA_NAME_CHECK (NODE)->base.public_flag
+
/* Returns the IDENTIFIER_NODE giving the SSA name a name or NULL_TREE
if there is no name associated with it. */
#define SSA_NAME_IDENTIFIER(NODE) \
? NULL_TREE : (NODE)->ssa_name.var)
#define SET_SSA_NAME_VAR_OR_IDENTIFIER(NODE,VAR) \
- do { SSA_NAME_CHECK (NODE)->ssa_name.var = (VAR); } while (0)
+ do \
+ { \
+ tree var_ = (VAR); \
+ SSA_NAME_CHECK (NODE)->ssa_name.var = var_; \
+ SSA_NAME_IS_VIRTUAL_OPERAND (NODE) \
+ = (var_ \
+ && TREE_CODE (var_) == VAR_DECL \
+ && VAR_DECL_IS_VIRTUAL_OPERAND (var_)); \
+ } \
+ while (0)
/* Returns the statement which defines this SSA name. */
#define SSA_NAME_DEF_STMT(NODE) SSA_NAME_CHECK (NODE)->ssa_name.def_stmt
/* True if BLOCK has the same ranges as its BLOCK_SUPERCONTEXT. */
#define BLOCK_SAME_RANGE(NODE) (BLOCK_CHECK (NODE)->base.u.bits.nameless_flag)
+/* True if BLOCK appears in cold section. */
+#define BLOCK_IN_COLD_SECTION_P(NODE) \
+ (BLOCK_CHECK (NODE)->base.u.bits.atomic_flag)
+
/* An index number for this block. These values are not guaranteed to
be unique across functions -- whether or not they are depends on
the debugging output format in use. */
#define TYPE_MAIN_VARIANT(NODE) (TYPE_CHECK (NODE)->type_common.main_variant)
#define TYPE_CONTEXT(NODE) (TYPE_CHECK (NODE)->type_common.context)
+#define TYPE_MODE_RAW(NODE) (TYPE_CHECK (NODE)->type_common.mode)
#define TYPE_MODE(NODE) \
(VECTOR_TYPE_P (TYPE_CHECK (NODE)) \
? vector_type_mode (NODE) : (NODE)->type_common.mode)
+#define SCALAR_TYPE_MODE(NODE) \
+ (as_a <scalar_mode> (TYPE_CHECK (NODE)->type_common.mode))
+#define SCALAR_INT_TYPE_MODE(NODE) \
+ (as_a <scalar_int_mode> (TYPE_CHECK (NODE)->type_common.mode))
+#define SCALAR_FLOAT_TYPE_MODE(NODE) \
+ (as_a <scalar_float_mode> (TYPE_CHECK (NODE)->type_common.mode))
#define SET_TYPE_MODE(NODE, MODE) \
(TYPE_CHECK (NODE)->type_common.mode = (MODE))
-extern machine_mode element_mode (const_tree t);
+extern machine_mode element_mode (const_tree);
+extern machine_mode vector_type_mode (const_tree);
/* The "canonical" type for this type node, which is used by frontends to
compare the type for equality with another type. If two types are
#define TYPE_ATTRIBUTES(NODE) (TYPE_CHECK (NODE)->type_common.attributes)
/* The alignment necessary for objects of this type.
- The value is an int, measured in bits. */
-#define TYPE_ALIGN(NODE) (TYPE_CHECK (NODE)->type_common.align)
+ The value is an int, measured in bits and must be a power of two.
+ We support also an "alignment" of zero. */
+#define TYPE_ALIGN(NODE) \
+ (TYPE_CHECK (NODE)->type_common.align \
+ ? ((unsigned)1) << ((NODE)->type_common.align - 1) : 0)
+
+/* Specify that TYPE_ALIGN(NODE) is X. */
+#define SET_TYPE_ALIGN(NODE, X) \
+ (TYPE_CHECK (NODE)->type_common.align = ffs_hwi (X))
/* 1 if the alignment for this type was requested by "aligned" attribute,
0 if it is the default for this type. */
/* The alignment for NODE, in bytes. */
#define TYPE_ALIGN_UNIT(NODE) (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
+/* The minimum alignment necessary for objects of this type without
+ warning. The value is an int, measured in bits. */
+#define TYPE_WARN_IF_NOT_ALIGN(NODE) \
+ (TYPE_CHECK (NODE)->type_common.warn_if_not_align \
+ ? ((unsigned)1) << ((NODE)->type_common.warn_if_not_align - 1) : 0)
+
+/* Specify that TYPE_WARN_IF_NOT_ALIGN(NODE) is X. */
+#define SET_TYPE_WARN_IF_NOT_ALIGN(NODE, X) \
+ (TYPE_CHECK (NODE)->type_common.warn_if_not_align = ffs_hwi (X))
+
/* If your language allows you to declare types, and you want debug info
for them, then you need to generate corresponding TYPE_DECL nodes.
These "stub" TYPE_DECL nodes have no name, and simply point at the
#define TYPE_LANG_FLAG_4(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_4)
#define TYPE_LANG_FLAG_5(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_5)
#define TYPE_LANG_FLAG_6(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_6)
+#define TYPE_LANG_FLAG_7(NODE) (TYPE_CHECK (NODE)->type_common.lang_flag_7)
/* Used to keep track of visited nodes in tree traversals. This is set to
0 by copy_node and make_node. */
If set in a INTEGER_TYPE, indicates a character type. */
#define TYPE_STRING_FLAG(NODE) (TYPE_CHECK (NODE)->type_common.string_flag)
-/* For a VECTOR_TYPE, this is the number of sub-parts of the vector. */
-#define TYPE_VECTOR_SUBPARTS(VECTOR_TYPE) \
- (((unsigned HOST_WIDE_INT) 1) \
- << VECTOR_TYPE_CHECK (VECTOR_TYPE)->type_common.precision)
-
-/* Set precision to n when we have 2^n sub-parts of the vector. */
-#define SET_TYPE_VECTOR_SUBPARTS(VECTOR_TYPE, X) \
- (VECTOR_TYPE_CHECK (VECTOR_TYPE)->type_common.precision = exact_log2 (X))
-
/* Nonzero in a VECTOR_TYPE if the frontends should not emit warnings
about missing conversions to other vector types of the same size. */
#define TYPE_VECTOR_OPAQUE(NODE) \
#define TYPE_NONALIASED_COMPONENT(NODE) \
(ARRAY_TYPE_CHECK (NODE)->type_common.transparent_aggr_flag)
+/* For an ARRAY_TYPE, a RECORD_TYPE, a UNION_TYPE or a QUAL_UNION_TYPE
+ whether the array is typeless storage or the type contains a member
+ with this flag set. Such types are exempt from type-based alias
+ analysis. For ARRAY_TYPEs with AGGREGATE_TYPE_P element types
+ the flag should be inherited from the element type, can change
+ when type is finalized and because of that should not be used in
+ type hashing. For ARRAY_TYPEs with non-AGGREGATE_TYPE_P element types
+ the flag should not be changed after the array is created and should
+ be used in type hashing. */
+#define TYPE_TYPELESS_STORAGE(NODE) \
+ (TREE_CHECK4 (NODE, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE, \
+ ARRAY_TYPE)->type_common.typeless_storage)
+
/* Indicated that objects of this type should be laid out in as
compact a way as possible. */
#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->base.u.bits.packed_flag)
#define TYPE_SYMTAB_ADDRESS(NODE) \
(TYPE_CHECK (NODE)->type_common.symtab.address)
-/* Symtab field as a string. Used by COFF generator in sdbout.c to
- hold struct/union type tag names. */
-#define TYPE_SYMTAB_POINTER(NODE) \
- (TYPE_CHECK (NODE)->type_common.symtab.pointer)
-
/* Symtab field as a pointer to a DWARF DIE. Used by DWARF generator
in dwarf2out.c to point to the DIE generated for the type. */
#define TYPE_SYMTAB_DIE(NODE) \
union. */
#define TYPE_SYMTAB_IS_ADDRESS (0)
-#define TYPE_SYMTAB_IS_POINTER (1)
-#define TYPE_SYMTAB_IS_DIE (2)
+#define TYPE_SYMTAB_IS_DIE (1)
#define TYPE_LANG_SPECIFIC(NODE) \
(TYPE_CHECK (NODE)->type_with_lang_specific.lang_specific)
#define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type_non_common.values)
#define TYPE_DOMAIN(NODE) (ARRAY_TYPE_CHECK (NODE)->type_non_common.values)
-#define TYPE_FIELDS(NODE) \
+#define TYPE_FIELDS(NODE) \
(RECORD_OR_UNION_CHECK (NODE)->type_non_common.values)
#define TYPE_CACHED_VALUES(NODE) (TYPE_CHECK (NODE)->type_non_common.values)
-#define TYPE_ARG_TYPES(NODE) \
+#define TYPE_ARG_TYPES(NODE) \
(FUNC_OR_METHOD_CHECK (NODE)->type_non_common.values)
#define TYPE_VALUES_RAW(NODE) (TYPE_CHECK (NODE)->type_non_common.values)
-#define TYPE_METHODS(NODE) \
- (RECORD_OR_UNION_CHECK (NODE)->type_non_common.maxval)
-#define TYPE_VFIELD(NODE) \
- (RECORD_OR_UNION_CHECK (NODE)->type_non_common.minval)
-#define TYPE_METHOD_BASETYPE(NODE) \
- (FUNC_OR_METHOD_CHECK (NODE)->type_non_common.maxval)
-#define TYPE_OFFSET_BASETYPE(NODE) \
- (OFFSET_TYPE_CHECK (NODE)->type_non_common.maxval)
-#define TYPE_MAXVAL(NODE) (TYPE_CHECK (NODE)->type_non_common.maxval)
-#define TYPE_MINVAL(NODE) (TYPE_CHECK (NODE)->type_non_common.minval)
-#define TYPE_NEXT_PTR_TO(NODE) \
+#define TYPE_MIN_VALUE(NODE) \
+ (NUMERICAL_TYPE_CHECK (NODE)->type_non_common.minval)
+#define TYPE_NEXT_PTR_TO(NODE) \
(POINTER_TYPE_CHECK (NODE)->type_non_common.minval)
-#define TYPE_NEXT_REF_TO(NODE) \
+#define TYPE_NEXT_REF_TO(NODE) \
(REFERENCE_TYPE_CHECK (NODE)->type_non_common.minval)
-#define TYPE_MIN_VALUE(NODE) \
- (NUMERICAL_TYPE_CHECK (NODE)->type_non_common.minval)
+#define TYPE_VFIELD(NODE) \
+ (RECORD_OR_UNION_CHECK (NODE)->type_non_common.minval)
+#define TYPE_MIN_VALUE_RAW(NODE) (TYPE_CHECK (NODE)->type_non_common.minval)
+
#define TYPE_MAX_VALUE(NODE) \
(NUMERICAL_TYPE_CHECK (NODE)->type_non_common.maxval)
-
+#define TYPE_METHOD_BASETYPE(NODE) \
+ (FUNC_OR_METHOD_CHECK (NODE)->type_non_common.maxval)
+#define TYPE_OFFSET_BASETYPE(NODE) \
+ (OFFSET_TYPE_CHECK (NODE)->type_non_common.maxval)
/* If non-NULL, this is an upper bound of the size (in bytes) of an
object of the given ARRAY_TYPE_NON_COMMON. This allows temporaries to be
allocated. */
#define TYPE_ARRAY_MAX_SIZE(ARRAY_TYPE) \
(ARRAY_TYPE_CHECK (ARRAY_TYPE)->type_non_common.maxval)
-
+#define TYPE_MAX_VALUE_RAW(NODE) (TYPE_CHECK (NODE)->type_non_common.maxval)
/* For record and union types, information about this type, as a base type
for itself. */
-#define TYPE_BINFO(NODE) (RECORD_OR_UNION_CHECK (NODE)->type_non_common.binfo)
+#define TYPE_BINFO(NODE) (RECORD_OR_UNION_CHECK (NODE)->type_non_common.maxval)
-/* For non record and union types, used in a language-dependent way. */
+/* For types, used in a language-dependent way. */
#define TYPE_LANG_SLOT_1(NODE) \
- (NOT_RECORD_OR_UNION_CHECK (NODE)->type_non_common.binfo)
+ (TYPE_CHECK (NODE)->type_non_common.lang_1)
/* Define accessor macros for information about type inheritance
and basetypes.
#define BINFO_VIRTUAL_P(NODE) (TREE_BINFO_CHECK (NODE)->base.static_flag)
/* Flags for language dependent use. */
-#define BINFO_MARKED(NODE) TREE_LANG_FLAG_0 (TREE_BINFO_CHECK (NODE))
+#define BINFO_FLAG_0(NODE) TREE_LANG_FLAG_0 (TREE_BINFO_CHECK (NODE))
#define BINFO_FLAG_1(NODE) TREE_LANG_FLAG_1 (TREE_BINFO_CHECK (NODE))
#define BINFO_FLAG_2(NODE) TREE_LANG_FLAG_2 (TREE_BINFO_CHECK (NODE))
#define BINFO_FLAG_3(NODE) TREE_LANG_FLAG_3 (TREE_BINFO_CHECK (NODE))
#define DECL_SIZE(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size)
/* Likewise for the size in bytes. */
#define DECL_SIZE_UNIT(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size_unit)
-/* Holds the alignment required for the datum, in bits. */
-#define DECL_ALIGN(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.align)
+/* Returns the alignment required for the datum, in bits. It must
+ be a power of two, but an "alignment" of zero is supported
+ (e.g. as "uninitialized" sentinel). */
+#define DECL_ALIGN(NODE) \
+ (DECL_COMMON_CHECK (NODE)->decl_common.align \
+ ? ((unsigned)1) << ((NODE)->decl_common.align - 1) : 0)
+/* Specify that DECL_ALIGN(NODE) is X. */
+#define SET_DECL_ALIGN(NODE, X) \
+ (DECL_COMMON_CHECK (NODE)->decl_common.align = ffs_hwi (X))
+
+/* The minimum alignment necessary for the datum, in bits, without
+ warning. */
+#define DECL_WARN_IF_NOT_ALIGN(NODE) \
+ (DECL_COMMON_CHECK (NODE)->decl_common.warn_if_not_align \
+ ? ((unsigned)1) << ((NODE)->decl_common.warn_if_not_align - 1) : 0)
+
+/* Specify that DECL_WARN_IF_NOT_ALIGN(NODE) is X. */
+#define SET_DECL_WARN_IF_NOT_ALIGN(NODE, X) \
+ (DECL_COMMON_CHECK (NODE)->decl_common.warn_if_not_align = ffs_hwi (X))
+
/* The alignment of NODE, in bytes. */
#define DECL_ALIGN_UNIT(NODE) (DECL_ALIGN (NODE) / BITS_PER_UNIT)
/* Set if the alignment of this DECL has been set by the user, for
field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
FIELD_DECL. */
#define DECL_MODE(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.mode)
+#define SET_DECL_MODE(NODE, MODE) \
+ (DECL_COMMON_CHECK (NODE)->decl_common.mode = (MODE))
/* For FUNCTION_DECL, if it is built-in, this identifies which built-in
operation it is. Note, however, that this field is overloaded, with
#define DECL_FUNCTION_CODE(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.function_code)
+/* Test if FCODE is a function code for an alloca operation. */
+#define ALLOCA_FUNCTION_CODE_P(FCODE) \
+ ((FCODE) == BUILT_IN_ALLOCA \
+ || (FCODE) == BUILT_IN_ALLOCA_WITH_ALIGN \
+ || (FCODE) == BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX)
+
+/* Generate case for an alloca operation. */
+#define CASE_BUILT_IN_ALLOCA \
+ case BUILT_IN_ALLOCA: \
+ case BUILT_IN_ALLOCA_WITH_ALIGN: \
+ case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX
+
#define DECL_FUNCTION_PERSONALITY(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.personality)
/* In a VAR_DECL or PARM_DECL, the location at which the value may be found,
if transformations have made this more complicated than evaluating the
- decl itself. This should only be used for debugging; once this field has
- been set, the decl itself may not legitimately appear in the function. */
+ decl itself. */
#define DECL_HAS_VALUE_EXPR_P(NODE) \
(TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \
->decl_common.decl_flag_2)
#define DECL_RTL_SET_P(NODE) \
(HAS_RTL_P (NODE) && DECL_WRTL_CHECK (NODE)->decl_with_rtl.rtl != NULL)
-/* Copy the RTL from NODE1 to NODE2. If the RTL was not set for
- NODE1, it will not be set for NODE2; this is a lazy copy. */
-#define COPY_DECL_RTL(NODE1, NODE2) \
- (DECL_WRTL_CHECK (NODE2)->decl_with_rtl.rtl \
- = DECL_WRTL_CHECK (NODE1)->decl_with_rtl.rtl)
+/* Copy the RTL from SRC_DECL to DST_DECL. If the RTL was not set for
+ SRC_DECL, it will not be set for DST_DECL; this is a lazy copy. */
+#define COPY_DECL_RTL(SRC_DECL, DST_DECL) \
+ (DECL_WRTL_CHECK (DST_DECL)->decl_with_rtl.rtl \
+ = DECL_WRTL_CHECK (SRC_DECL)->decl_with_rtl.rtl)
/* The DECL_RTL for NODE, if it is set, or NULL, if it is not set. */
#define DECL_RTL_IF_SET(NODE) (DECL_RTL_SET_P (NODE) ? DECL_RTL (NODE) : NULL)
#define DECL_OFFSET_ALIGN(NODE) \
(((unsigned HOST_WIDE_INT)1) << FIELD_DECL_CHECK (NODE)->decl_common.off_align)
-/* Specify that DECL_ALIGN(NODE) is a multiple of X. */
+/* Specify that DECL_OFFSET_ALIGN(NODE) is X. */
#define SET_DECL_OFFSET_ALIGN(NODE, X) \
(FIELD_DECL_CHECK (NODE)->decl_common.off_align = ffs_hwi (X) - 1)
#define DECL_NONADDRESSABLE_P(NODE) \
(FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_2)
+/* Used in a FIELD_DECL to indicate that this field is padding. */
+#define DECL_PADDING_P(NODE) \
+ (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_3)
+
/* A numeric unique identifier for a LABEL_DECL. The UID allocation is
dense, unique within any one function, and may be used to index arrays.
If the value is -1, then no UID has been assigned. */
LTO compilation and C++. */
#define DECL_ASSEMBLER_NAME(NODE) decl_assembler_name (NODE)
+/* Raw accessor for DECL_ASSEMBLE_NAME. */
+#define DECL_ASSEMBLER_NAME_RAW(NODE) \
+ (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.assembler_name)
+
/* Return true if NODE is a NODE that can contain a DECL_ASSEMBLER_NAME.
This is true of all DECL nodes except FIELD_DECL. */
#define HAS_DECL_ASSEMBLER_NAME_P(NODE) \
the NODE might still have a DECL_ASSEMBLER_NAME -- it just hasn't been set
yet. */
#define DECL_ASSEMBLER_NAME_SET_P(NODE) \
- (HAS_DECL_ASSEMBLER_NAME_P (NODE) \
- && DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.assembler_name != NULL_TREE)
+ (DECL_ASSEMBLER_NAME_RAW (NODE) != NULL_TREE)
/* Set the DECL_ASSEMBLER_NAME for NODE to NAME. */
#define SET_DECL_ASSEMBLER_NAME(NODE, NAME) \
- (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.assembler_name = (NAME))
+ overwrite_decl_assembler_name (NODE, NAME)
-/* Copy the DECL_ASSEMBLER_NAME from DECL1 to DECL2. Note that if DECL1's
- DECL_ASSEMBLER_NAME has not yet been set, using this macro will not cause
- the DECL_ASSEMBLER_NAME of either DECL to be set. In other words, the
- semantics of using this macro, are different than saying:
+/* Copy the DECL_ASSEMBLER_NAME from SRC_DECL to DST_DECL. Note that
+ if SRC_DECL's DECL_ASSEMBLER_NAME has not yet been set, using this
+ macro will not cause the DECL_ASSEMBLER_NAME to be set, but will
+ clear DECL_ASSEMBLER_NAME of DST_DECL, if it was already set. In
+ other words, the semantics of using this macro, are different than
+ saying:
- SET_DECL_ASSEMBLER_NAME(DECL2, DECL_ASSEMBLER_NAME (DECL1))
+ SET_DECL_ASSEMBLER_NAME(DST_DECL, DECL_ASSEMBLER_NAME (SRC_DECL))
- which will try to set the DECL_ASSEMBLER_NAME for DECL1. */
+ which will try to set the DECL_ASSEMBLER_NAME for SRC_DECL. */
-#define COPY_DECL_ASSEMBLER_NAME(DECL1, DECL2) \
- (DECL_ASSEMBLER_NAME_SET_P (DECL1) \
- ? (void) SET_DECL_ASSEMBLER_NAME (DECL2, \
- DECL_ASSEMBLER_NAME (DECL1)) \
- : (void) 0)
+#define COPY_DECL_ASSEMBLER_NAME(SRC_DECL, DST_DECL) \
+ SET_DECL_ASSEMBLER_NAME (DST_DECL, DECL_ASSEMBLER_NAME_RAW (SRC_DECL))
/* Records the section name in a section attribute. Used to pass
the name from decl_attributes to make_function_rtl and make_decl_rtl. */
#endif
+/* True iff an identifier matches a C string. */
+
+inline bool
+id_equal (const_tree id, const char *str)
+{
+ return !strcmp (IDENTIFIER_POINTER (id), str);
+}
+
+inline bool
+id_equal (const char *str, const_tree id)
+{
+ return !strcmp (str, IDENTIFIER_POINTER (id));
+}
+
+/* Return the number of elements in the VECTOR_TYPE given by NODE. */
+
+inline poly_uint64
+TYPE_VECTOR_SUBPARTS (const_tree node)
+{
+ STATIC_ASSERT (NUM_POLY_INT_COEFFS <= 2);
+ unsigned int precision = VECTOR_TYPE_CHECK (node)->type_common.precision;
+ if (NUM_POLY_INT_COEFFS == 2)
+ {
+ poly_uint64 res = 0;
+ res.coeffs[0] = 1 << (precision & 0xff);
+ if (precision & 0x100)
+ res.coeffs[1] = 1 << (precision & 0xff);
+ return res;
+ }
+ else
+ return 1 << precision;
+}
+
+/* Set the number of elements in VECTOR_TYPE NODE to SUBPARTS, which must
+ satisfy valid_vector_subparts_p. */
+
+inline void
+SET_TYPE_VECTOR_SUBPARTS (tree node, poly_uint64 subparts)
+{
+ STATIC_ASSERT (NUM_POLY_INT_COEFFS <= 2);
+ unsigned HOST_WIDE_INT coeff0 = subparts.coeffs[0];
+ int index = exact_log2 (coeff0);
+ gcc_assert (index >= 0);
+ if (NUM_POLY_INT_COEFFS == 2)
+ {
+ unsigned HOST_WIDE_INT coeff1 = subparts.coeffs[1];
+ gcc_assert (coeff1 == 0 || coeff1 == coeff0);
+ VECTOR_TYPE_CHECK (node)->type_common.precision
+ = index + (coeff1 != 0 ? 0x100 : 0);
+ }
+ else
+ VECTOR_TYPE_CHECK (node)->type_common.precision = index;
+}
+
+/* Return true if we can construct vector types with the given number
+ of subparts. */
+
+static inline bool
+valid_vector_subparts_p (poly_uint64 subparts)
+{
+ unsigned HOST_WIDE_INT coeff0 = subparts.coeffs[0];
+ if (!pow2p_hwi (coeff0))
+ return false;
+ if (NUM_POLY_INT_COEFFS == 2)
+ {
+ unsigned HOST_WIDE_INT coeff1 = subparts.coeffs[1];
+ if (coeff1 != 0 && coeff1 != coeff0)
+ return false;
+ }
+ return true;
+}
+
#define error_mark_node global_trees[TI_ERROR_MARK]
#define intQI_type_node global_trees[TI_INTQI_TYPE]
#define double_type_node global_trees[TI_DOUBLE_TYPE]
#define long_double_type_node global_trees[TI_LONG_DOUBLE_TYPE]
+/* Nodes for particular _FloatN and _FloatNx types in sequence. */
+#define FLOATN_TYPE_NODE(IDX) global_trees[TI_FLOATN_TYPE_FIRST + (IDX)]
+#define FLOATN_NX_TYPE_NODE(IDX) global_trees[TI_FLOATN_NX_TYPE_FIRST + (IDX)]
+#define FLOATNX_TYPE_NODE(IDX) global_trees[TI_FLOATNX_TYPE_FIRST + (IDX)]
+
+/* Names for individual types (code should normally iterate over all
+ such types; these are only for back-end use, or in contexts such as
+ *.def where iteration is not possible). */
+#define float16_type_node global_trees[TI_FLOAT16_TYPE]
+#define float32_type_node global_trees[TI_FLOAT32_TYPE]
+#define float64_type_node global_trees[TI_FLOAT64_TYPE]
+#define float128_type_node global_trees[TI_FLOAT128_TYPE]
+#define float32x_type_node global_trees[TI_FLOAT32X_TYPE]
+#define float64x_type_node global_trees[TI_FLOAT64X_TYPE]
+#define float128x_type_node global_trees[TI_FLOAT128X_TYPE]
+
#define float_ptr_type_node global_trees[TI_FLOAT_PTR_TYPE]
#define double_ptr_type_node global_trees[TI_DOUBLE_PTR_TYPE]
#define long_double_ptr_type_node global_trees[TI_LONG_DOUBLE_PTR_TYPE]
#define complex_double_type_node global_trees[TI_COMPLEX_DOUBLE_TYPE]
#define complex_long_double_type_node global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE]
+#define COMPLEX_FLOATN_NX_TYPE_NODE(IDX) global_trees[TI_COMPLEX_FLOATN_NX_TYPE_FIRST + (IDX)]
+
#define pointer_bounds_type_node global_trees[TI_POINTER_BOUNDS_TYPE]
#define void_type_node global_trees[TI_VOID_TYPE]
#define va_list_fpr_counter_field global_trees[TI_VA_LIST_FPR_COUNTER_FIELD]
/* The C type `FILE *'. */
#define fileptr_type_node global_trees[TI_FILEPTR_TYPE]
+/* The C type `const struct tm *'. */
+#define const_tm_ptr_type_node global_trees[TI_CONST_TM_PTR_TYPE]
+/* The C type `fenv_t *'. */
+#define fenv_t_ptr_type_node global_trees[TI_FENV_T_PTR_TYPE]
+#define const_fenv_t_ptr_type_node global_trees[TI_CONST_FENV_T_PTR_TYPE]
+/* The C type `fexcept_t *'. */
+#define fexcept_t_ptr_type_node global_trees[TI_FEXCEPT_T_PTR_TYPE]
+#define const_fexcept_t_ptr_type_node global_trees[TI_CONST_FEXCEPT_T_PTR_TYPE]
#define pointer_sized_int_node global_trees[TI_POINTER_SIZED_TYPE]
#define boolean_type_node global_trees[TI_BOOLEAN_TYPE]
((NODE) == error_mark_node \
|| ((NODE) && TREE_TYPE ((NODE)) == error_mark_node))
+/* Return the number of elements encoded directly in a VECTOR_CST. */
+
+inline unsigned int
+vector_cst_encoded_nelts (const_tree t)
+{
+ return VECTOR_CST_NPATTERNS (t) * VECTOR_CST_NELTS_PER_PATTERN (t);
+}
+
extern tree decl_assembler_name (tree);
+extern void overwrite_decl_assembler_name (tree decl, tree name);
extern tree decl_comdat_group (const_tree);
extern tree decl_comdat_group_id (const_tree);
extern const char *decl_section_name (const_tree);
The TREE_CODE is the only argument. Contents are initialized
to zero except for a few of the common fields. */
-extern tree make_node_stat (enum tree_code MEM_STAT_DECL);
-#define make_node(t) make_node_stat (t MEM_STAT_INFO)
+extern tree make_node (enum tree_code CXX_MEM_STAT_INFO);
+
+/* Free tree node. */
+
+extern void free_node (tree);
/* Make a copy of a node, with all the same contents. */
-extern tree copy_node_stat (tree MEM_STAT_DECL);
-#define copy_node(t) copy_node_stat (t MEM_STAT_INFO)
+extern tree copy_node (tree CXX_MEM_STAT_INFO);
/* Make a copy of a chain of TREE_LIST nodes. */
extern tree build_case_label (tree, tree, tree);
/* Make a BINFO. */
-extern tree make_tree_binfo_stat (unsigned MEM_STAT_DECL);
-#define make_tree_binfo(t) make_tree_binfo_stat (t MEM_STAT_INFO)
+extern tree make_tree_binfo (unsigned CXX_MEM_STAT_INFO);
/* Make an INTEGER_CST. */
-extern tree make_int_cst_stat (int, int MEM_STAT_DECL);
-#define make_int_cst(LEN, EXT_LEN) \
- make_int_cst_stat (LEN, EXT_LEN MEM_STAT_INFO)
+extern tree make_int_cst (int, int CXX_MEM_STAT_INFO);
/* Make a TREE_VEC. */
-extern tree make_tree_vec_stat (int MEM_STAT_DECL);
-#define make_tree_vec(t) make_tree_vec_stat (t MEM_STAT_INFO)
+extern tree make_tree_vec (int CXX_MEM_STAT_INFO);
/* Grow a TREE_VEC. */
-extern tree grow_tree_vec_stat (tree v, int MEM_STAT_DECL);
-#define grow_tree_vec(v, t) grow_tree_vec_stat (v, t MEM_STAT_INFO)
+extern tree grow_tree_vec (tree v, int CXX_MEM_STAT_INFO);
/* Construct various types of nodes. */
extern tree build_nt (enum tree_code, ...);
extern tree build_nt_call_vec (tree, vec<tree, va_gc> *);
-extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL);
-#define build0(c,t) build0_stat (c,t MEM_STAT_INFO)
-extern tree build1_stat (enum tree_code, tree, tree MEM_STAT_DECL);
-#define build1(c,t1,t2) build1_stat (c,t1,t2 MEM_STAT_INFO)
-extern tree build2_stat (enum tree_code, tree, tree, tree MEM_STAT_DECL);
-#define build2(c,t1,t2,t3) build2_stat (c,t1,t2,t3 MEM_STAT_INFO)
-extern tree build3_stat (enum tree_code, tree, tree, tree, tree MEM_STAT_DECL);
-#define build3(c,t1,t2,t3,t4) build3_stat (c,t1,t2,t3,t4 MEM_STAT_INFO)
-extern tree build4_stat (enum tree_code, tree, tree, tree, tree,
- tree MEM_STAT_DECL);
-#define build4(c,t1,t2,t3,t4,t5) build4_stat (c,t1,t2,t3,t4,t5 MEM_STAT_INFO)
-extern tree build5_stat (enum tree_code, tree, tree, tree, tree, tree,
- tree MEM_STAT_DECL);
-#define build5(c,t1,t2,t3,t4,t5,t6) build5_stat (c,t1,t2,t3,t4,t5,t6 MEM_STAT_INFO)
+extern tree build0 (enum tree_code, tree CXX_MEM_STAT_INFO);
+extern tree build1 (enum tree_code, tree, tree CXX_MEM_STAT_INFO);
+extern tree build2 (enum tree_code, tree, tree, tree CXX_MEM_STAT_INFO);
+extern tree build3 (enum tree_code, tree, tree, tree, tree CXX_MEM_STAT_INFO);
+extern tree build4 (enum tree_code, tree, tree, tree, tree,
+ tree CXX_MEM_STAT_INFO);
+extern tree build5 (enum tree_code, tree, tree, tree, tree, tree,
+ tree CXX_MEM_STAT_INFO);
/* _loc versions of build[1-5]. */
static inline tree
-build1_stat_loc (location_t loc, enum tree_code code, tree type,
- tree arg1 MEM_STAT_DECL)
+build1_loc (location_t loc, enum tree_code code, tree type,
+ tree arg1 CXX_MEM_STAT_INFO)
{
- tree t = build1_stat (code, type, arg1 PASS_MEM_STAT);
+ tree t = build1 (code, type, arg1 PASS_MEM_STAT);
if (CAN_HAVE_LOCATION_P (t))
SET_EXPR_LOCATION (t, loc);
return t;
}
-#define build1_loc(l,c,t1,t2) build1_stat_loc (l,c,t1,t2 MEM_STAT_INFO)
static inline tree
-build2_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
- tree arg1 MEM_STAT_DECL)
+build2_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+ tree arg1 CXX_MEM_STAT_INFO)
{
- tree t = build2_stat (code, type, arg0, arg1 PASS_MEM_STAT);
+ tree t = build2 (code, type, arg0, arg1 PASS_MEM_STAT);
if (CAN_HAVE_LOCATION_P (t))
SET_EXPR_LOCATION (t, loc);
return t;
}
-#define build2_loc(l,c,t1,t2,t3) build2_stat_loc (l,c,t1,t2,t3 MEM_STAT_INFO)
static inline tree
-build3_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
- tree arg1, tree arg2 MEM_STAT_DECL)
+build3_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+ tree arg1, tree arg2 CXX_MEM_STAT_INFO)
{
- tree t = build3_stat (code, type, arg0, arg1, arg2 PASS_MEM_STAT);
+ tree t = build3 (code, type, arg0, arg1, arg2 PASS_MEM_STAT);
if (CAN_HAVE_LOCATION_P (t))
SET_EXPR_LOCATION (t, loc);
return t;
}
-#define build3_loc(l,c,t1,t2,t3,t4) \
- build3_stat_loc (l,c,t1,t2,t3,t4 MEM_STAT_INFO)
static inline tree
-build4_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
- tree arg1, tree arg2, tree arg3 MEM_STAT_DECL)
+build4_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+ tree arg1, tree arg2, tree arg3 CXX_MEM_STAT_INFO)
{
- tree t = build4_stat (code, type, arg0, arg1, arg2, arg3 PASS_MEM_STAT);
+ tree t = build4 (code, type, arg0, arg1, arg2, arg3 PASS_MEM_STAT);
if (CAN_HAVE_LOCATION_P (t))
SET_EXPR_LOCATION (t, loc);
return t;
}
-#define build4_loc(l,c,t1,t2,t3,t4,t5) \
- build4_stat_loc (l,c,t1,t2,t3,t4,t5 MEM_STAT_INFO)
static inline tree
-build5_stat_loc (location_t loc, enum tree_code code, tree type, tree arg0,
- tree arg1, tree arg2, tree arg3, tree arg4 MEM_STAT_DECL)
+build5_loc (location_t loc, enum tree_code code, tree type, tree arg0,
+ tree arg1, tree arg2, tree arg3, tree arg4 CXX_MEM_STAT_INFO)
{
- tree t = build5_stat (code, type, arg0, arg1, arg2, arg3,
+ tree t = build5 (code, type, arg0, arg1, arg2, arg3,
arg4 PASS_MEM_STAT);
if (CAN_HAVE_LOCATION_P (t))
SET_EXPR_LOCATION (t, loc);
return t;
}
-#define build5_loc(l,c,t1,t2,t3,t4,t5,t6) \
- build5_stat_loc (l,c,t1,t2,t3,t4,t5,t6 MEM_STAT_INFO)
-
-extern tree build_var_debug_value_stat (tree, tree MEM_STAT_DECL);
-#define build_var_debug_value(t1,t2) \
- build_var_debug_value_stat (t1,t2 MEM_STAT_INFO)
/* Constructs double_int from tree CST. */
extern tree double_int_to_tree (tree, double_int);
-extern tree wide_int_to_tree (tree type, const wide_int_ref &cst);
-extern tree force_fit_type (tree, const wide_int_ref &, int, bool);
+extern tree wide_int_to_tree (tree type, const poly_wide_int_ref &cst);
+extern tree force_fit_type (tree, const poly_wide_int_ref &, int, bool);
/* Create an INT_CST node with a CST value zero extended. */
/* static inline */
-extern tree build_int_cst (tree, HOST_WIDE_INT);
-extern tree build_int_cstu (tree type, unsigned HOST_WIDE_INT cst);
-extern tree build_int_cst_type (tree, HOST_WIDE_INT);
-extern tree make_vector_stat (unsigned MEM_STAT_DECL);
-#define make_vector(n) make_vector_stat (n MEM_STAT_INFO)
-extern tree build_vector_stat (tree, tree * MEM_STAT_DECL);
-#define build_vector(t,v) build_vector_stat (t, v MEM_STAT_INFO)
+extern tree build_int_cst (tree, poly_int64);
+extern tree build_int_cstu (tree type, poly_uint64);
+extern tree build_int_cst_type (tree, poly_int64);
+extern tree make_vector (unsigned, unsigned CXX_MEM_STAT_INFO);
extern tree build_vector_from_ctor (tree, vec<constructor_elt, va_gc> *);
extern tree build_vector_from_val (tree, tree);
+extern tree build_vec_series (tree, tree, tree);
+extern tree build_index_vector (tree, poly_uint64, poly_uint64);
+extern void recompute_constructor_flags (tree);
+extern void verify_constructor_flags (tree);
extern tree build_constructor (tree, vec<constructor_elt, va_gc> *);
extern tree build_constructor_single (tree, tree, tree);
extern tree build_constructor_from_list (tree, tree);
extern tree build_all_ones_cst (tree);
extern tree build_zero_cst (tree);
extern tree build_string (int, const char *);
-extern tree build_tree_list_stat (tree, tree MEM_STAT_DECL);
-#define build_tree_list(t, q) build_tree_list_stat (t, q MEM_STAT_INFO)
-extern tree build_tree_list_vec_stat (const vec<tree, va_gc> *MEM_STAT_DECL);
-#define build_tree_list_vec(v) build_tree_list_vec_stat (v MEM_STAT_INFO)
-extern tree build_decl_stat (location_t, enum tree_code,
- tree, tree MEM_STAT_DECL);
+extern tree build_poly_int_cst (tree, const poly_wide_int_ref &);
+extern tree build_tree_list (tree, tree CXX_MEM_STAT_INFO);
+extern tree build_tree_list_vec (const vec<tree, va_gc> * CXX_MEM_STAT_INFO);
+extern tree build_decl (location_t, enum tree_code,
+ tree, tree CXX_MEM_STAT_INFO);
extern tree build_fn_decl (const char *, tree);
-#define build_decl(l,c,t,q) build_decl_stat (l, c, t, q MEM_STAT_INFO)
extern tree build_translation_unit_decl (tree);
extern tree build_block (tree, tree, tree, tree);
extern tree build_empty_stmt (location_t);
extern tree build_omp_clause (location_t, enum omp_clause_code);
-extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
-#define build_vl_exp(c, n) build_vl_exp_stat (c, n MEM_STAT_INFO)
+extern tree build_vl_exp (enum tree_code, int CXX_MEM_STAT_INFO);
extern tree build_call_nary (tree, tree, int, ...);
extern tree build_call_valist (tree, tree, int, va_list);
extern tree build_call_expr (tree, int, ...);
extern tree build_call_expr_internal_loc (location_t, enum internal_fn,
tree, int, ...);
+extern tree build_call_expr_internal_loc_array (location_t, enum internal_fn,
+ tree, int, const tree *);
+extern tree maybe_build_call_expr_loc (location_t, combined_fn, tree,
+ int, ...);
+extern tree build_alloca_call_expr (tree, unsigned int, HOST_WIDE_INT);
extern tree build_string_literal (int, const char *);
/* Construct various nodes representing data types. */
extern tree build_reference_type_for_mode (tree, machine_mode, bool);
extern tree build_reference_type (tree);
extern tree build_vector_type_for_mode (tree, machine_mode);
-extern tree build_vector_type (tree innertype, int nunits);
-extern tree build_truth_vector_type (unsigned, unsigned);
+extern tree build_vector_type (tree, poly_int64);
+extern tree build_truth_vector_type (poly_uint64, poly_uint64);
extern tree build_same_sized_truth_vector_type (tree vectype);
-extern tree build_opaque_vector_type (tree innertype, int nunits);
+extern tree build_opaque_vector_type (tree, poly_int64);
extern tree build_index_type (tree);
-extern tree build_array_type (tree, tree);
+extern tree build_array_type (tree, tree, bool = false);
extern tree build_nonshared_array_type (tree, tree);
-extern tree build_array_type_nelts (tree, unsigned HOST_WIDE_INT);
+extern tree build_array_type_nelts (tree, poly_uint64);
extern tree build_function_type (tree, tree);
extern tree build_function_type_list (tree, ...);
extern tree build_varargs_function_type_list (tree, ...);
extern tree build_method_type_directly (tree, tree, tree);
extern tree build_method_type (tree, tree);
extern tree build_offset_type (tree, tree);
-extern tree build_complex_type (tree);
+extern tree build_complex_type (tree, bool named = false);
extern tree array_type_nelts (const_tree);
extern tree value_member (tree, tree);
extern bool vec_member (const_tree, vec<tree, va_gc> *);
extern tree chain_index (int, tree);
-extern int attribute_list_equal (const_tree, const_tree);
-extern int attribute_list_contained (const_tree, const_tree);
extern int tree_int_cst_equal (const_tree, const_tree);
-extern bool tree_fits_shwi_p (const_tree)
-#ifndef ENABLE_TREE_CHECKING
- ATTRIBUTE_PURE /* tree_fits_shwi_p is pure only when checking is disabled. */
-#endif
- ;
-extern bool tree_fits_uhwi_p (const_tree)
-#ifndef ENABLE_TREE_CHECKING
- ATTRIBUTE_PURE /* tree_fits_uhwi_p is pure only when checking is disabled. */
-#endif
- ;
+extern bool tree_fits_shwi_p (const_tree) ATTRIBUTE_PURE;
+extern bool tree_fits_poly_int64_p (const_tree) ATTRIBUTE_PURE;
+extern bool tree_fits_uhwi_p (const_tree) ATTRIBUTE_PURE;
+extern bool tree_fits_poly_uint64_p (const_tree) ATTRIBUTE_PURE;
extern HOST_WIDE_INT tree_to_shwi (const_tree);
+extern poly_int64 tree_to_poly_int64 (const_tree);
extern unsigned HOST_WIDE_INT tree_to_uhwi (const_tree);
+extern poly_uint64 tree_to_poly_uint64 (const_tree);
#if !defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 4003)
extern inline __attribute__ ((__gnu_inline__)) HOST_WIDE_INT
tree_to_shwi (const_tree t)
gcc_assert (tree_fits_uhwi_p (t));
return TREE_INT_CST_LOW (t);
}
+#if NUM_POLY_INT_COEFFS == 1
+extern inline __attribute__ ((__gnu_inline__)) poly_int64
+tree_to_poly_int64 (const_tree t)
+{
+ gcc_assert (tree_fits_poly_int64_p (t));
+ return TREE_INT_CST_LOW (t);
+}
+
+extern inline __attribute__ ((__gnu_inline__)) poly_uint64
+tree_to_poly_uint64 (const_tree t)
+{
+ gcc_assert (tree_fits_poly_uint64_p (t));
+ return TREE_INT_CST_LOW (t);
+}
+#endif
#endif
extern int tree_int_cst_sgn (const_tree);
extern int tree_int_cst_sign_bit (const_tree);
extern tree excess_precision_type (tree);
extern bool valid_constant_size_p (const_tree);
+/* Return true if T holds a value that can be represented as a poly_int64
+ without loss of precision. Store the value in *VALUE if so. */
-/* From expmed.c. Since rtl.h is included after tree.h, we can't
- put the prototype here. Rtl.h does declare the prototype if
- tree.h had been included. */
-
-extern tree make_tree (tree, rtx);
-
-/* Return a type like TTYPE except that its TYPE_ATTRIBUTES
- is ATTRIBUTE.
-
- Such modified types already made are recorded so that duplicates
- are not made. */
-
-extern tree build_type_attribute_variant (tree, tree);
-extern tree build_decl_attribute_variant (tree, tree);
-extern tree build_type_attribute_qual_variant (tree, tree, int);
-
-extern bool attribute_value_equal (const_tree, const_tree);
-
-/* Return 0 if the attributes for two types are incompatible, 1 if they
- are compatible, and 2 if they are nearly compatible (which causes a
- warning to be generated). */
-extern int comp_type_attributes (const_tree, const_tree);
-
-/* Default versions of target-overridable functions. */
-extern tree merge_decl_attributes (tree, tree);
-extern tree merge_type_attributes (tree, tree);
-
-/* This function is a private implementation detail of lookup_attribute()
- and you should never call it directly. */
-extern tree private_lookup_attribute (const char *, size_t, tree);
-
-/* This function is a private implementation detail
- of lookup_attribute_by_prefix() and you should never call it directly. */
-extern tree private_lookup_attribute_by_prefix (const char *, size_t, tree);
-
-/* Given an attribute name ATTR_NAME and a list of attributes LIST,
- return a pointer to the attribute's list element if the attribute
- is part of the list, or NULL_TREE if not found. If the attribute
- appears more than once, this only returns the first occurrence; the
- TREE_CHAIN of the return value should be passed back in if further
- occurrences are wanted. ATTR_NAME must be in the form 'text' (not
- '__text__'). */
-
-static inline tree
-lookup_attribute (const char *attr_name, tree list)
-{
- gcc_checking_assert (attr_name[0] != '_');
- /* In most cases, list is NULL_TREE. */
- if (list == NULL_TREE)
- return NULL_TREE;
- else
- /* Do the strlen() before calling the out-of-line implementation.
- In most cases attr_name is a string constant, and the compiler
- will optimize the strlen() away. */
- return private_lookup_attribute (attr_name, strlen (attr_name), list);
-}
-
-/* Given an attribute name ATTR_NAME and a list of attributes LIST,
- return a pointer to the attribute's list first element if the attribute
- starts with ATTR_NAME. ATTR_NAME must be in the form 'text' (not
- '__text__'). */
-
-static inline tree
-lookup_attribute_by_prefix (const char *attr_name, tree list)
+inline bool
+poly_int_tree_p (const_tree t, poly_int64_pod *value)
{
- gcc_checking_assert (attr_name[0] != '_');
- /* In most cases, list is NULL_TREE. */
- if (list == NULL_TREE)
- return NULL_TREE;
- else
- return private_lookup_attribute_by_prefix (attr_name, strlen (attr_name),
- list);
+ if (tree_fits_poly_int64_p (t))
+ {
+ *value = tree_to_poly_int64 (t);
+ return true;
+ }
+ return false;
}
+/* Return true if T holds a value that can be represented as a poly_uint64
+ without loss of precision. Store the value in *VALUE if so. */
-/* This function is a private implementation detail of
- is_attribute_p() and you should never call it directly. */
-extern bool private_is_attribute_p (const char *, size_t, const_tree);
-
-/* Given an identifier node IDENT and a string ATTR_NAME, return true
- if the identifier node is a valid attribute name for the string.
- ATTR_NAME must be in the form 'text' (not '__text__'). IDENT could
- be the identifier for 'text' or for '__text__'. */
-
-static inline bool
-is_attribute_p (const char *attr_name, const_tree ident)
+inline bool
+poly_int_tree_p (const_tree t, poly_uint64_pod *value)
{
- gcc_checking_assert (attr_name[0] != '_');
- /* Do the strlen() before calling the out-of-line implementation.
- In most cases attr_name is a string constant, and the compiler
- will optimize the strlen() away. */
- return private_is_attribute_p (attr_name, strlen (attr_name), ident);
+ if (tree_fits_poly_uint64_p (t))
+ {
+ *value = tree_to_poly_uint64 (t);
+ return true;
+ }
+ return false;
}
-/* Remove any instances of attribute ATTR_NAME in LIST and return the
- modified list. ATTR_NAME must be in the form 'text' (not
- '__text__'). */
-
-extern tree remove_attribute (const char *, tree);
-
-/* Given two attributes lists, return a list of their union. */
+/* From expmed.c. Since rtl.h is included after tree.h, we can't
+ put the prototype here. Rtl.h does declare the prototype if
+ tree.h had been included. */
-extern tree merge_attributes (tree, tree);
+extern tree make_tree (tree, rtx);
-/* Given two Windows decl attributes lists, possibly including
- dllimport, return a list of their union . */
-extern tree merge_dllimport_decl_attributes (tree, tree);
+/* Returns true iff CAND and BASE have equivalent language-specific
+ qualifiers. */
-/* Handle a "dllimport" or "dllexport" attribute. */
-extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);
+extern bool check_lang_type (const_tree cand, const_tree base);
/* Returns true iff unqualified CAND and BASE are equivalent. */
/* Like get_qualified_type, but creates the type if it does not
exist. This function never returns NULL_TREE. */
-extern tree build_qualified_type (tree, int);
+extern tree build_qualified_type (tree, int CXX_MEM_STAT_INFO);
/* Create a variant of type T with alignment ALIGN. */
/* Make a copy of a type node. */
-extern tree build_distinct_type_copy (tree);
-extern tree build_variant_type_copy (tree);
+extern tree build_distinct_type_copy (tree CXX_MEM_STAT_INFO);
+extern tree build_variant_type_copy (tree CXX_MEM_STAT_INFO);
/* Given a hashcode and a ..._TYPE node (for which the hashcode was made),
return a canonicalized ..._TYPE node, so that duplicates are not made.
How the hash code is computed is up to the caller, as long as any two
callers that could hash identical-looking type nodes agree. */
+extern hashval_t type_hash_canon_hash (tree);
extern tree type_hash_canon (unsigned int, tree);
extern tree convert (tree, tree);
extern unsigned int expr_align (const_tree);
-extern tree size_in_bytes (const_tree);
+extern tree size_in_bytes_loc (location_t, const_tree);
+inline tree
+size_in_bytes (const_tree t)
+{
+ return size_in_bytes_loc (input_location, t);
+}
+
extern HOST_WIDE_INT int_size_in_bytes (const_tree);
extern HOST_WIDE_INT max_int_size_in_bytes (const_tree);
extern tree bit_position (const_tree);
extern tree byte_position (const_tree);
extern HOST_WIDE_INT int_byte_position (const_tree);
+/* Type for sizes of data-type. */
+
#define sizetype sizetype_tab[(int) stk_sizetype]
#define bitsizetype sizetype_tab[(int) stk_bitsizetype]
#define ssizetype sizetype_tab[(int) stk_ssizetype]
#define bitsize_int(L) size_int_kind (L, stk_bitsizetype)
#define sbitsize_int(L) size_int_kind (L, stk_sbitsizetype)
-/* Type for sizes of data-type. */
+/* Log2 of BITS_PER_UNIT. */
-#define BITS_PER_UNIT_LOG \
- ((BITS_PER_UNIT > 1) + (BITS_PER_UNIT > 2) + (BITS_PER_UNIT > 4) \
- + (BITS_PER_UNIT > 8) + (BITS_PER_UNIT > 16) + (BITS_PER_UNIT > 32) \
- + (BITS_PER_UNIT > 64) + (BITS_PER_UNIT > 128) + (BITS_PER_UNIT > 256))
+#if BITS_PER_UNIT == 8
+#define LOG2_BITS_PER_UNIT 3
+#elif BITS_PER_UNIT == 16
+#define LOG2_BITS_PER_UNIT 4
+#else
+#error Unknown BITS_PER_UNIT
+#endif
/* Concatenate two lists (chains of TREE_LIST nodes) X and Y
by making the last node in X point to Y.
/* Make a new TREE_LIST node from specified PURPOSE, VALUE and CHAIN. */
-extern tree tree_cons_stat (tree, tree, tree MEM_STAT_DECL);
-#define tree_cons(t,q,w) tree_cons_stat (t,q,w MEM_STAT_INFO)
+extern tree tree_cons (tree, tree, tree CXX_MEM_STAT_INFO);
/* Return the last tree node in a chain. */
extern bool initializer_zerop (const_tree);
+extern wide_int vector_cst_int_elt (const_tree, unsigned int);
+extern tree vector_cst_elt (const_tree, unsigned int);
+
/* Given a vector VEC, return its first element if all elements are
the same. Otherwise return NULL_TREE. */
extern tree save_expr (tree);
+/* Return true if T is function-invariant. */
+
+extern bool tree_invariant_p (tree);
+
/* Look inside EXPR into any simple arithmetic operations. Return the
outermost non-arithmetic or non-invariant node. */
extern tree get_containing_scope (const_tree);
+/* Returns the ultimate TRANSLATION_UNIT_DECL context of DECL or NULL. */
+
+extern const_tree get_ultimate_context (const_tree);
+
/* Return the FUNCTION_DECL which provides this _DECL with its context,
or zero if none. */
extern tree decl_function_context (const_tree);
function_args_iter_next (&(ITER)))
/* In tree.c */
+extern unsigned crc32_unsigned_n (unsigned, unsigned, unsigned);
extern unsigned crc32_string (unsigned, const char *);
-extern unsigned crc32_byte (unsigned, char);
-extern unsigned crc32_unsigned (unsigned, unsigned);
+inline unsigned
+crc32_unsigned (unsigned chksum, unsigned value)
+{
+ return crc32_unsigned_n (chksum, value, 4);
+}
+inline unsigned
+crc32_byte (unsigned chksum, char byte)
+{
+ return crc32_unsigned_n (chksum, byte, 1);
+}
extern void clean_symbol_name (char *);
extern tree get_file_function_name (const char *);
extern tree get_callee_fndecl (const_tree);
extern tree tree_strip_sign_nop_conversions (tree);
extern const_tree strip_invariant_refs (const_tree);
extern tree lhd_gcc_personality (void);
-extern void assign_assembler_name_if_neeeded (tree);
+extern void assign_assembler_name_if_needed (tree);
extern void warn_deprecated_use (tree, tree);
extern void cache_integer_cst (tree);
extern const char *combined_fn_name (combined_fn);
-/* Return the memory model from a host integer. */
-static inline enum memmodel
-memmodel_from_int (unsigned HOST_WIDE_INT val)
-{
- return (enum memmodel) (val & MEMMODEL_MASK);
-}
-
-/* Return the base memory model from a host integer. */
-static inline enum memmodel
-memmodel_base (unsigned HOST_WIDE_INT val)
-{
- return (enum memmodel) (val & MEMMODEL_BASE_MASK);
-}
-
-/* Return TRUE if the memory model is RELAXED. */
-static inline bool
-is_mm_relaxed (enum memmodel model)
-{
- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELAXED;
-}
-
-/* Return TRUE if the memory model is CONSUME. */
-static inline bool
-is_mm_consume (enum memmodel model)
-{
- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_CONSUME;
-}
-
-/* Return TRUE if the memory model is ACQUIRE. */
-static inline bool
-is_mm_acquire (enum memmodel model)
-{
- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQUIRE;
-}
-
-/* Return TRUE if the memory model is RELEASE. */
-static inline bool
-is_mm_release (enum memmodel model)
-{
- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELEASE;
-}
-
-/* Return TRUE if the memory model is ACQ_REL. */
-static inline bool
-is_mm_acq_rel (enum memmodel model)
-{
- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQ_REL;
-}
-
-/* Return TRUE if the memory model is SEQ_CST. */
-static inline bool
-is_mm_seq_cst (enum memmodel model)
-{
- return (model & MEMMODEL_BASE_MASK) == MEMMODEL_SEQ_CST;
-}
-
-/* Return TRUE if the memory model is a SYNC variant. */
-static inline bool
-is_mm_sync (enum memmodel model)
-{
- return (model & MEMMODEL_SYNC);
-}
-
/* Compare and hash for any structure which begins with a canonical
pointer. Assumes all pointers are interchangeable, which is sort
of already assumed by gcc elsewhere IIRC. */
&& TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype));
}
+/* Return true if the argument is a complete type or an array
+ of unknown bound (whose type is incomplete but) whose elements
+ have complete type. */
+static inline bool
+complete_or_array_type_p (const_tree type)
+{
+ return COMPLETE_TYPE_P (type)
+ || (TREE_CODE (type) == ARRAY_TYPE
+ && COMPLETE_TYPE_P (TREE_TYPE (type)));
+}
+
+/* Return true if the value of T could be represented as a poly_widest_int. */
+
+inline bool
+poly_int_tree_p (const_tree t)
+{
+ return (TREE_CODE (t) == INTEGER_CST || POLY_INT_CST_P (t));
+}
+
+/* Return the bit size of BIT_FIELD_REF T, in cases where it is known
+ to be a poly_uint64. (This is always true at the gimple level.) */
+
+inline poly_uint64
+bit_field_size (const_tree t)
+{
+ return tree_to_poly_uint64 (TREE_OPERAND (t, 1));
+}
+
+/* Return the starting bit offset of BIT_FIELD_REF T, in cases where it is
+ known to be a poly_uint64. (This is always true at the gimple level.) */
+
+inline poly_uint64
+bit_field_offset (const_tree t)
+{
+ return tree_to_poly_uint64 (TREE_OPERAND (t, 2));
+}
+
extern tree strip_float_extensions (tree);
extern int really_constant_p (const_tree);
+extern bool ptrdiff_tree_p (const_tree, poly_int64_pod *);
extern bool decl_address_invariant_p (const_tree);
extern bool decl_address_ip_invariant_p (const_tree);
extern bool int_fits_type_p (const_tree, const_tree);
namespace inchash
{
-extern void add_expr (const_tree, hash &);
+extern void add_expr (const_tree, hash &, unsigned int = 0);
}
extern int real_onep (const_tree);
extern int real_minus_onep (const_tree);
extern void init_ttree (void);
-extern void build_common_tree_nodes (bool, bool);
+extern void build_common_tree_nodes (bool);
extern void build_common_builtin_nodes (void);
extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int);
extern tree build_nonstandard_boolean_type (unsigned HOST_WIDE_INT);
extern location_t *block_nonartificial_location (tree);
extern location_t tree_nonartificial_location (tree);
extern tree block_ultimate_origin (const_tree);
-extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
+extern tree get_binfo_at_offset (tree, poly_int64, tree);
extern bool virtual_method_call_p (const_tree);
extern tree obj_type_ref_class (const_tree ref);
extern bool types_same_for_odr (const_tree type1, const_tree type2,
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
extern tree array_ref_low_bound (tree);
-/* Returns true if REF is an array reference to an array at the end of
- a structure. If this is the case, the array may be allocated larger
- than its upper bound implies. */
+/* Returns true if REF is an array reference or a component reference
+ to an array at the end of a structure. If this is the case, the array
+ may be allocated larger than its upper bound implies. */
extern bool array_at_struct_end_p (tree);
/* Return a tree representing the offset, in bytes, of the field referenced
extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
bool trust_type_canonical = true);
extern bool type_with_interoperable_signedness (const_tree);
-/* Return simplified tree code of type that is used for canonical type merging. */
+extern bitmap get_nonnull_args (const_tree);
+extern int get_range_pos_neg (tree);
+
+/* Return simplified tree code of type that is used for canonical type
+ merging. */
inline enum tree_code
tree_code_for_canonical_type_merging (enum tree_code code)
{
return code;
}
+/* Return ture if get_alias_set care about TYPE_CANONICAL of given type.
+ We don't define the types for pointers, arrays and vectors. The reason is
+ that pointers are handled specially: ptr_type_node accesses conflict with
+ accesses to all other pointers. This is done by alias.c.
+ Because alias sets of arrays and vectors are the same as types of their
+ elements, we can't compute canonical type either. Otherwise we could go
+ form void *[10] to int *[10] (because they are equivalent for canonical type
+ machinery) and get wrong TBAA. */
+
+inline bool
+canonical_type_used_p (const_tree t)
+{
+ return !(POINTER_TYPE_P (t)
+ || TREE_CODE (t) == ARRAY_TYPE
+ || TREE_CODE (t) == VECTOR_TYPE);
+}
+
#define tree_map_eq tree_map_base_eq
extern unsigned int tree_map_hash (const void *);
#define tree_map_marked_p tree_map_base_marked_p
#define tree_vec_map_hash tree_decl_map_hash
#define tree_vec_map_marked_p tree_map_base_marked_p
+/* A hash_map of two trees for use with GTY((cache)). Garbage collection for
+ such a map will not mark keys, and will mark values if the key is already
+ marked. */
+struct tree_cache_traits
+ : simple_cache_map_traits<default_hash_traits<tree>, tree> { };
+typedef hash_map<tree,tree,tree_cache_traits> tree_cache_map;
+
/* Initialize the abstract argument list iterator object ITER with the
arguments from CALL_EXPR node EXP. */
static inline void
/* The tree and const_tree overload templates. */
namespace wi
{
+ class unextended_tree
+ {
+ private:
+ const_tree m_t;
+
+ public:
+ unextended_tree () {}
+ unextended_tree (const_tree t) : m_t (t) {}
+
+ unsigned int get_precision () const;
+ const HOST_WIDE_INT *get_val () const;
+ unsigned int get_len () const;
+ const_tree get_tree () const { return m_t; }
+ };
+
template <>
- struct int_traits <const_tree>
+ struct int_traits <unextended_tree>
{
static const enum precision_type precision_type = VAR_PRECISION;
static const bool host_dependent_precision = false;
static const bool is_sign_extended = false;
- static unsigned int get_precision (const_tree);
- static wi::storage_ref decompose (HOST_WIDE_INT *, unsigned int,
- const_tree);
};
- template <>
- struct int_traits <tree> : public int_traits <const_tree> {};
-
template <int N>
class extended_tree
{
const_tree m_t;
public:
+ extended_tree () {}
extended_tree (const_tree);
unsigned int get_precision () const;
const HOST_WIDE_INT *get_val () const;
unsigned int get_len () const;
+ const_tree get_tree () const { return m_t; }
};
template <int N>
static const unsigned int precision = N;
};
- generic_wide_int <extended_tree <WIDE_INT_MAX_PRECISION> >
- to_widest (const_tree);
+ typedef extended_tree <WIDE_INT_MAX_PRECISION> widest_extended_tree;
+ typedef extended_tree <ADDR_MAX_PRECISION> offset_extended_tree;
+
+ typedef const generic_wide_int <widest_extended_tree> tree_to_widest_ref;
+ typedef const generic_wide_int <offset_extended_tree> tree_to_offset_ref;
+ typedef const generic_wide_int<wide_int_ref_storage<false, false> >
+ tree_to_wide_ref;
+
+ tree_to_widest_ref to_widest (const_tree);
+ tree_to_offset_ref to_offset (const_tree);
+ tree_to_wide_ref to_wide (const_tree);
+ wide_int to_wide (const_tree, unsigned int);
+
+ typedef const poly_int <NUM_POLY_INT_COEFFS,
+ generic_wide_int <widest_extended_tree> >
+ tree_to_poly_widest_ref;
+ typedef const poly_int <NUM_POLY_INT_COEFFS,
+ generic_wide_int <offset_extended_tree> >
+ tree_to_poly_offset_ref;
+ typedef const poly_int <NUM_POLY_INT_COEFFS,
+ generic_wide_int <unextended_tree> >
+ tree_to_poly_wide_ref;
+
+ tree_to_poly_widest_ref to_poly_widest (const_tree);
+ tree_to_poly_offset_ref to_poly_offset (const_tree);
+ tree_to_poly_wide_ref to_poly_wide (const_tree);
- generic_wide_int <extended_tree <ADDR_MAX_PRECISION> > to_offset (const_tree);
-}
+ template <int N>
+ struct ints_for <generic_wide_int <extended_tree <N> >, CONST_PRECISION>
+ {
+ typedef generic_wide_int <extended_tree <N> > extended;
+ static extended zero (const extended &);
+ };
-inline unsigned int
-wi::int_traits <const_tree>::get_precision (const_tree tcst)
-{
- return TYPE_PRECISION (TREE_TYPE (tcst));
+ template <>
+ struct ints_for <generic_wide_int <unextended_tree>, VAR_PRECISION>
+ {
+ typedef generic_wide_int <unextended_tree> unextended;
+ static unextended zero (const unextended &);
+ };
}
-/* Convert the tree_cst X into a wide_int of PRECISION. */
-inline wi::storage_ref
-wi::int_traits <const_tree>::decompose (HOST_WIDE_INT *,
- unsigned int precision, const_tree x)
-{
- return wi::storage_ref (&TREE_INT_CST_ELT (x, 0), TREE_INT_CST_NUNITS (x),
- precision);
-}
+/* Refer to INTEGER_CST T as though it were a widest_int.
+
+ This function gives T's actual numerical value, influenced by the
+ signedness of its type. For example, a signed byte with just the
+ top bit set would be -128 while an unsigned byte with the same
+ bit pattern would be 128.
+
+ This is the right choice when operating on groups of INTEGER_CSTs
+ that might have different signedness or precision. It is also the
+ right choice in code that specifically needs an approximation of
+ infinite-precision arithmetic instead of normal modulo arithmetic.
+
+ The approximation of infinite precision is good enough for realistic
+ numbers of additions and subtractions of INTEGER_CSTs (where
+ "realistic" includes any number less than 1 << 31) but it cannot
+ represent the result of multiplying the two largest supported
+ INTEGER_CSTs. The overflow-checking form of wi::mul provides a way
+ of multiplying two arbitrary INTEGER_CSTs and checking that the
+ result is representable as a widest_int.
+
+ Note that any overflow checking done on these values is relative to
+ the range of widest_int rather than the range of a TREE_TYPE.
-inline generic_wide_int <wi::extended_tree <WIDE_INT_MAX_PRECISION> >
+ Calling this function should have no overhead in release builds,
+ so it is OK to call it several times for the same tree. If it is
+ useful for readability reasons to reduce the number of calls,
+ it is more efficient to use:
+
+ wi::tree_to_widest_ref wt = wi::to_widest (t);
+
+ instead of:
+
+ widest_int wt = wi::to_widest (t). */
+
+inline wi::tree_to_widest_ref
wi::to_widest (const_tree t)
{
return t;
}
-inline generic_wide_int <wi::extended_tree <ADDR_MAX_PRECISION> >
+/* Refer to INTEGER_CST T as though it were an offset_int.
+
+ This function is an optimisation of wi::to_widest for cases
+ in which T is known to be a bit or byte count in the range
+ (-(2 ^ (N + BITS_PER_UNIT)), 2 ^ (N + BITS_PER_UNIT)), where N is
+ the target's address size in bits.
+
+ This is the right choice when operating on bit or byte counts as
+ untyped numbers rather than M-bit values. The wi::to_widest comments
+ about addition, subtraction and multiplication apply here: sequences
+ of 1 << 31 additions and subtractions do not induce overflow, but
+ multiplying the largest sizes might. Again,
+
+ wi::tree_to_offset_ref wt = wi::to_offset (t);
+
+ is more efficient than:
+
+ offset_int wt = wi::to_offset (t). */
+
+inline wi::tree_to_offset_ref
wi::to_offset (const_tree t)
{
return t;
}
+/* Refer to INTEGER_CST T as though it were a wide_int.
+
+ In contrast to the approximation of infinite-precision numbers given
+ by wi::to_widest and wi::to_offset, this function treats T as a
+ signless collection of N bits, where N is the precision of T's type.
+ As with machine registers, signedness is determined by the operation
+ rather than the operands; for example, there is a distinction between
+ signed and unsigned division.
+
+ This is the right choice when operating on values with the same type
+ using normal modulo arithmetic. The overflow-checking forms of things
+ like wi::add check whether the result can be represented in T's type.
+
+ Calling this function should have no overhead in release builds,
+ so it is OK to call it several times for the same tree. If it is
+ useful for readability reasons to reduce the number of calls,
+ it is more efficient to use:
+
+ wi::tree_to_wide_ref wt = wi::to_wide (t);
+
+ instead of:
+
+ wide_int wt = wi::to_wide (t). */
+
+inline wi::tree_to_wide_ref
+wi::to_wide (const_tree t)
+{
+ return wi::storage_ref (&TREE_INT_CST_ELT (t, 0), TREE_INT_CST_NUNITS (t),
+ TYPE_PRECISION (TREE_TYPE (t)));
+}
+
+/* Convert INTEGER_CST T to a wide_int of precision PREC, extending or
+ truncating as necessary. When extending, use sign extension if T's
+ type is signed and zero extension if T's type is unsigned. */
+
+inline wide_int
+wi::to_wide (const_tree t, unsigned int prec)
+{
+ return wide_int::from (wi::to_wide (t), prec, TYPE_SIGN (TREE_TYPE (t)));
+}
+
template <int N>
inline wi::extended_tree <N>::extended_tree (const_tree t)
: m_t (t)
gcc_unreachable ();
}
+inline unsigned int
+wi::unextended_tree::get_precision () const
+{
+ return TYPE_PRECISION (TREE_TYPE (m_t));
+}
+
+inline const HOST_WIDE_INT *
+wi::unextended_tree::get_val () const
+{
+ return &TREE_INT_CST_ELT (m_t, 0);
+}
+
+inline unsigned int
+wi::unextended_tree::get_len () const
+{
+ return TREE_INT_CST_NUNITS (m_t);
+}
+
+/* Return the value of a POLY_INT_CST in its native precision. */
+
+inline wi::tree_to_poly_wide_ref
+poly_int_cst_value (const_tree x)
+{
+ poly_int <NUM_POLY_INT_COEFFS, generic_wide_int <wi::unextended_tree> > res;
+ for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+ res.coeffs[i] = POLY_INT_CST_COEFF (x, i);
+ return res;
+}
+
+/* Access INTEGER_CST or POLY_INT_CST tree T as if it were a
+ poly_widest_int. See wi::to_widest for more details. */
+
+inline wi::tree_to_poly_widest_ref
+wi::to_poly_widest (const_tree t)
+{
+ if (POLY_INT_CST_P (t))
+ {
+ poly_int <NUM_POLY_INT_COEFFS,
+ generic_wide_int <widest_extended_tree> > res;
+ for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+ res.coeffs[i] = POLY_INT_CST_COEFF (t, i);
+ return res;
+ }
+ return t;
+}
+
+/* Access INTEGER_CST or POLY_INT_CST tree T as if it were a
+ poly_offset_int. See wi::to_offset for more details. */
+
+inline wi::tree_to_poly_offset_ref
+wi::to_poly_offset (const_tree t)
+{
+ if (POLY_INT_CST_P (t))
+ {
+ poly_int <NUM_POLY_INT_COEFFS,
+ generic_wide_int <offset_extended_tree> > res;
+ for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+ res.coeffs[i] = POLY_INT_CST_COEFF (t, i);
+ return res;
+ }
+ return t;
+}
+
+/* Access INTEGER_CST or POLY_INT_CST tree T as if it were a
+ poly_wide_int. See wi::to_wide for more details. */
+
+inline wi::tree_to_poly_wide_ref
+wi::to_poly_wide (const_tree t)
+{
+ if (POLY_INT_CST_P (t))
+ return poly_int_cst_value (t);
+ return t;
+}
+
+template <int N>
+inline generic_wide_int <wi::extended_tree <N> >
+wi::ints_for <generic_wide_int <wi::extended_tree <N> >,
+ wi::CONST_PRECISION>::zero (const extended &x)
+{
+ return build_zero_cst (TREE_TYPE (x.get_tree ()));
+}
+
+inline generic_wide_int <wi::unextended_tree>
+wi::ints_for <generic_wide_int <wi::unextended_tree>,
+ wi::VAR_PRECISION>::zero (const unextended &x)
+{
+ return build_zero_cst (TREE_TYPE (x.get_tree ()));
+}
+
namespace wi
{
template <typename T>
+ bool fits_to_boolean_p (const T &x, const_tree);
+
+ template <typename T>
bool fits_to_tree_p (const T &x, const_tree);
wide_int min_value (const_tree);
template <typename T>
bool
+wi::fits_to_boolean_p (const T &x, const_tree type)
+{
+ typedef typename poly_int_traits<T>::int_type int_type;
+ return (known_eq (x, int_type (0))
+ || known_eq (x, int_type (TYPE_UNSIGNED (type) ? 1 : -1)));
+}
+
+template <typename T>
+bool
wi::fits_to_tree_p (const T &x, const_tree type)
{
- if (TYPE_SIGN (type) == UNSIGNED)
- return eq_p (x, zext (x, TYPE_PRECISION (type)));
+ /* 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 fits_to_boolean_p (x, type);
+
+ if (TYPE_UNSIGNED (type))
+ return known_eq (x, zext (x, TYPE_PRECISION (type)));
else
- return eq_p (x, sext (x, TYPE_PRECISION (type)));
+ return known_eq (x, sext (x, TYPE_PRECISION (type)));
}
/* Produce the smallest number that is represented in TYPE. The precision
inline bool
tree_int_cst_lt (const_tree t1, const_tree t2)
{
- return wi::lts_p (wi::to_widest (t1), wi::to_widest (t2));
+ return wi::to_widest (t1) < wi::to_widest (t2);
}
/* Return true if INTEGER_CST T1 is less than or equal to INTEGER_CST T2,
inline bool
tree_int_cst_le (const_tree t1, const_tree t2)
{
- return wi::les_p (wi::to_widest (t1), wi::to_widest (t2));
+ return wi::to_widest (t1) <= wi::to_widest (t2);
}
/* Returns -1 if T1 < T2, 0 if T1 == T2, and 1 if T1 > T2. T1 and T2
/* Given an expression EXP that is a handled_component_p,
look for the ultimate containing object, which is returned and specify
the access position and size. */
-extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
- tree *, machine_mode *, int *, int *,
- int *, bool);
+extern tree get_inner_reference (tree, poly_int64_pod *, poly_int64_pod *,
+ tree *, machine_mode *, int *, int *, int *);
extern tree build_personality_function (const char *);
inline HOST_WIDE_INT
int_bit_position (const_tree field)
-{
- return (wi::lshift (wi::to_offset (DECL_FIELD_OFFSET (field)), BITS_PER_UNIT_LOG)
+{
+ return ((wi::to_offset (DECL_FIELD_OFFSET (field)) << LOG2_BITS_PER_UNIT)
+ wi::to_offset (DECL_FIELD_BIT_OFFSET (field))).to_shwi ();
}
extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
extern bool nonnull_arg_p (const_tree);
+extern bool is_redundant_typedef (const_tree);
+extern bool default_is_empty_record (const_tree);
+extern HOST_WIDE_INT arg_int_size_in_bytes (const_tree);
+extern tree arg_size_in_bytes (const_tree);
+extern bool expr_type_first_operand_type_p (tree_code);
-extern void
+extern location_t
set_source_range (tree expr, location_t start, location_t finish);
-extern void
+extern location_t
set_source_range (tree expr, source_range src_range);
static inline source_range
return get_range_from_loc (line_table, loc);
}
+/* Return true if it makes sense to promote/demote from_type to to_type. */
+inline bool
+desired_pro_or_demotion_p (const_tree to_type, const_tree from_type)
+{
+ unsigned int to_type_precision = TYPE_PRECISION (to_type);
+
+ /* OK to promote if to_type is no bigger than word_mode. */
+ if (to_type_precision <= GET_MODE_PRECISION (word_mode))
+ return true;
+
+ /* Otherwise, allow only if narrowing or same precision conversions. */
+ return to_type_precision <= TYPE_PRECISION (from_type);
+}
+
+/* Pointer type used to declare builtins before we have seen its real
+ declaration. */
+struct builtin_structptr_type
+{
+ tree& node;
+ tree& base;
+ const char *str;
+};
+extern const builtin_structptr_type builtin_structptr_types[6];
+
+/* Return true if type T has the same precision as its underlying mode. */
+
+inline bool
+type_has_mode_precision_p (const_tree t)
+{
+ return TYPE_PRECISION (t) == GET_MODE_PRECISION (TYPE_MODE (t));
+}
+
#endif /* GCC_TREE_H */