/* Definitions for the ubiquitous 'tree' type for GNU compilers.
- Copyright (C) 1989-2017 Free Software Foundation, Inc.
+ Copyright (C) 1989-2020 Free Software Foundation, Inc.
This file is part of GCC.
(MARK_TS_TYPE_COMMON (C), \
tree_contains_struct[C][TS_TYPE_WITH_LANG_SPECIFIC] = true)
+#define MARK_TS_TYPE_NON_COMMON(C) \
+ (MARK_TS_TYPE_WITH_LANG_SPECIFIC (C), \
+ tree_contains_struct[C][TS_TYPE_NON_COMMON] = true) \
+
#define MARK_TS_DECL_MINIMAL(C) \
(MARK_TS_COMMON (C), \
tree_contains_struct[C][TS_DECL_MINIMAL] = true)
(MARK_TS_DECL_WITH_VIS (C), \
tree_contains_struct[C][TS_DECL_NON_COMMON] = true)
+#define MARK_TS_EXP(C) \
+ (MARK_TS_TYPED (C), \
+ tree_contains_struct[C][TS_EXP] = true)
+
/* Returns the string representing CLASS. */
#define TREE_CODE_CLASS_STRING(CLASS)\
#define CONSTANT_CLASS_P(NODE)\
(TREE_CODE_CLASS (TREE_CODE (NODE)) == tcc_constant)
+/* Nonzero if NODE represents a constant, or is a location wrapper
+ around such a node. */
+
+#define CONSTANT_CLASS_OR_WRAPPER_P(NODE)\
+ (CONSTANT_CLASS_P (tree_strip_any_location_wrapper (NODE)))
+
/* Nonzero if NODE represents a type. */
#define TYPE_P(NODE)\
TREE_CHECK3 (T, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE)
#define NOT_RECORD_OR_UNION_CHECK(T) \
TREE_NOT_CHECK3 (T, RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE)
+#define ARRAY_OR_INTEGER_TYPE_CHECK(T) \
+ TREE_CHECK2 (T, ARRAY_TYPE, INTEGER_TYPE)
#define NUMERICAL_TYPE_CHECK(T) \
TREE_CHECK5 (T, INTEGER_TYPE, ENUMERAL_TYPE, BOOLEAN_TYPE, REAL_TYPE, \
#define STRIP_USELESS_TYPE_CONVERSION(EXP) \
(EXP) = tree_ssa_strip_useless_type_conversions (EXP)
+/* Remove any VIEW_CONVERT_EXPR or NON_LVALUE_EXPR that's purely
+ in use to provide a location_t. */
+
+#define STRIP_ANY_LOCATION_WRAPPER(EXP) \
+ (EXP) = tree_strip_any_location_wrapper (CONST_CAST_TREE (EXP))
+
/* Nonzero if TYPE represents a vector type. */
#define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE)
/* Nonzero if this type is a complete type. */
#define COMPLETE_TYPE_P(NODE) (TYPE_SIZE (NODE) != NULL_TREE)
-/* Nonzero if this type is a pointer bounds type. */
-#define POINTER_BOUNDS_TYPE_P(NODE) \
- (TREE_CODE (NODE) == POINTER_BOUNDS_TYPE)
-
-/* Nonzero if this node has a pointer bounds type. */
-#define POINTER_BOUNDS_P(NODE) \
- (POINTER_BOUNDS_TYPE_P (TREE_TYPE (NODE)))
-
-/* Nonzero if this type supposes bounds existence. */
-#define BOUNDED_TYPE_P(type) (POINTER_TYPE_P (type))
-
-/* Nonzero for objects with bounded type. */
-#define BOUNDED_P(node) \
- BOUNDED_TYPE_P (TREE_TYPE (node))
-
/* Nonzero if this type is the (possibly qualified) void type. */
#define VOID_TYPE_P(NODE) (TREE_CODE (NODE) == VOID_TYPE)
/* Used to indicate that this TYPE represents a compiler-generated entity. */
#define TYPE_ARTIFICIAL(NODE) (TYPE_CHECK (NODE)->base.nowarning_flag)
+/* True if the type is indivisible at the source level, i.e. if its
+ component parts cannot be accessed directly. This is used to suppress
+ normal GNU extensions for target-specific vector types. */
+#define TYPE_INDIVISIBLE_P(NODE) (TYPE_CHECK (NODE)->type_common.indivisible_p)
+
/* In an IDENTIFIER_NODE, this means that assemble_name was called with
this string as an argument. */
#define TREE_SYMBOL_REFERENCED(NODE) \
/* Same as TYPE_UNSIGNED but converted to SIGNOP. */
#define TYPE_SIGN(NODE) ((signop) TYPE_UNSIGNED (NODE))
-/* True if overflow wraps around for the given integral type. That
+/* True if overflow wraps around for the given integral or pointer type. That
is, TYPE_MAX + 1 == TYPE_MIN. */
#define TYPE_OVERFLOW_WRAPS(TYPE) \
- (ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag || flag_wrapv)
+ (POINTER_TYPE_P (TYPE) \
+ ? flag_wrapv_pointer \
+ : (ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag \
+ || flag_wrapv))
-/* True if overflow is undefined for the given integral type. We may
- optimize on the assumption that values in the type never overflow.
+/* True if overflow is undefined for the given integral or pointer type.
+ We may optimize on the assumption that values in the type never overflow.
IMPORTANT NOTE: Any optimization based on TYPE_OVERFLOW_UNDEFINED
must issue a warning based on warn_strict_overflow. In some cases
other cases it will be appropriate to simply set a flag and let the
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)
+ (POINTER_TYPE_P (TYPE) \
+ ? !flag_wrapv_pointer \
+ : (!ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag \
+ && !flag_wrapv && !flag_trapv))
/* True if overflow for the given integral type should issue a
trap. */
(TREE_CHECK2 (NODE, VAR_DECL, \
RESULT_DECL)->decl_common.decl_nonshareable_flag)
+/* In a PARM_DECL, set for Fortran hidden string length arguments that some
+ buggy callers don't pass to the callee. */
+#define DECL_HIDDEN_STRING_LENGTH(NODE) \
+ (TREE_CHECK (NODE, PARM_DECL)->decl_common.decl_nonshareable_flag)
+
/* In a CALL_EXPR, means that the call is the jump from a thunk to the
thunked-to function. */
#define CALL_FROM_THUNK_P(NODE) (CALL_EXPR_CHECK (NODE)->base.protected_flag)
#define CALL_ALLOCA_FOR_VAR_P(NODE) \
(CALL_EXPR_CHECK (NODE)->base.protected_flag)
-/* 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)
-
/* Used in classes in C++. */
#define TREE_PRIVATE(NODE) ((NODE)->base.private_flag)
/* Used in classes in C++. */
#define TREE_DEPRECATED(NODE) \
((NODE)->base.deprecated_flag)
+/* Nonzero indicates an IDENTIFIER_NODE that names an anonymous
+ aggregate, (as created by anon_aggr_name_format). */
+#define IDENTIFIER_ANON_P(NODE) \
+ (IDENTIFIER_NODE_CHECK (NODE)->base.private_flag)
+
/* Nonzero in an IDENTIFIER_NODE if the name is a local alias, whose
uses are to be substituted for uses of the TREE_CHAINed identifier. */
#define IDENTIFIER_TRANSPARENT_ALIAS(NODE) \
#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))
((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 0 /* debug_nonbind_markers_p */
+#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
}
extern void protected_set_expr_location (tree, location_t);
+extern void protected_set_expr_location_if_unset (tree, location_t);
+
+extern tree maybe_wrap_with_location (tree, location_t);
+
+extern int suppress_location_wrappers;
+
+/* A class for suppressing the creation of location wrappers.
+ Location wrappers will not be created during the lifetime
+ of an instance of this class. */
+
+class auto_suppress_location_wrappers
+{
+ public:
+ auto_suppress_location_wrappers () { ++suppress_location_wrappers; }
+ ~auto_suppress_location_wrappers () { --suppress_location_wrappers; }
+};
/* In a TARGET_EXPR node. */
#define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
#define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1)
#define TARGET_EXPR_CLEANUP(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 2)
+/* Don't elide the initialization of TARGET_EXPR_SLOT for this TARGET_EXPR
+ on rhs of MODIFY_EXPR. */
+#define TARGET_EXPR_NO_ELIDE(NODE) (TARGET_EXPR_CHECK (NODE)->base.private_flag)
/* DECL_EXPR accessor. This gives access to the DECL associated with
the given declaration statement. */
ASM_OPERAND with no operands. */
#define ASM_INPUT_P(NODE) (ASM_EXPR_CHECK (NODE)->base.static_flag)
#define ASM_VOLATILE_P(NODE) (ASM_EXPR_CHECK (NODE)->base.public_flag)
+/* Nonzero if we want to consider this asm as minimum length and cost
+ for inlining decisions. */
+#define ASM_INLINE_P(NODE) (ASM_EXPR_CHECK (NODE)->base.protected_flag)
/* COND_EXPR accessors. */
#define COND_EXPR_COND(NODE) (TREE_OPERAND (COND_EXPR_CHECK (NODE), 0))
/* Generic accessors for OMP nodes that keep the body as operand 0, and clauses
as operand 1. */
#define OMP_BODY(NODE) \
- TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_TASKGROUP), 0)
+ TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_MASTER), 0)
#define OMP_CLAUSES(NODE) \
- TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_SINGLE), 1)
+ TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_SCAN), 1)
/* Generic accessors for OMP nodes that keep clauses as operand 0. */
#define OMP_STANDALONE_CLAUSES(NODE) \
#define OMP_TASKREG_BODY(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 0)
#define OMP_TASKREG_CLAUSES(NODE) TREE_OPERAND (OMP_TASKREG_CHECK (NODE), 1)
-#define OMP_LOOP_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_FOR, OACC_LOOP)
-#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 0)
-#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 1)
-#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 2)
-#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 3)
-#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 4)
-#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 5)
-#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 6)
+#define OMP_LOOPING_CHECK(NODE) TREE_RANGE_CHECK (NODE, OMP_FOR, OACC_LOOP)
+#define OMP_FOR_BODY(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 0)
+#define OMP_FOR_CLAUSES(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 1)
+#define OMP_FOR_INIT(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 2)
+#define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 3)
+#define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 4)
+#define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 5)
+#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_LOOPING_CHECK (NODE), 6)
#define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0)
#define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1)
#define OMP_MASTER_BODY(NODE) TREE_OPERAND (OMP_MASTER_CHECK (NODE), 0)
#define OMP_TASKGROUP_BODY(NODE) TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 0)
+#define OMP_TASKGROUP_CLAUSES(NODE) \
+ TREE_OPERAND (OMP_TASKGROUP_CHECK (NODE), 1)
#define OMP_ORDERED_BODY(NODE) TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 0)
#define OMP_ORDERED_CLAUSES(NODE) TREE_OPERAND (OMP_ORDERED_CHECK (NODE), 1)
#define OMP_TARGET_EXIT_DATA_CLAUSES(NODE)\
TREE_OPERAND (OMP_TARGET_EXIT_DATA_CHECK (NODE), 0)
+#define OMP_SCAN_BODY(NODE) TREE_OPERAND (OMP_SCAN_CHECK (NODE), 0)
+#define OMP_SCAN_CLAUSES(NODE) TREE_OPERAND (OMP_SCAN_CHECK (NODE), 1)
+
#define OMP_CLAUSE_SIZE(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
OMP_CLAUSE_FROM, \
#define OMP_CLAUSE_DECL(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
OMP_CLAUSE_PRIVATE, \
- OMP_CLAUSE__LOOPTEMP_), 0)
+ OMP_CLAUSE__SCANTEMP_), 0)
#define OMP_CLAUSE_HAS_LOCATION(NODE) \
(LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \
!= UNKNOWN_LOCATION)
#define OMP_TARGET_COMBINED(NODE) \
(OMP_TARGET_CHECK (NODE)->base.private_flag)
-/* True if OMP_ATOMIC* is supposed to be sequentially consistent
- as opposed to relaxed. */
-#define OMP_ATOMIC_SEQ_CST(NODE) \
+/* Memory order for OMP_ATOMIC*. */
+#define OMP_ATOMIC_MEMORY_ORDER(NODE) \
(TREE_RANGE_CHECK (NODE, OMP_ATOMIC, \
- OMP_ATOMIC_CAPTURE_NEW)->base.private_flag)
+ OMP_ATOMIC_CAPTURE_NEW)->base.u.omp_atomic_memory_order)
/* True on a PRIVATE clause if its decl is kept around for debugging
information only and its DECL_VALUE_EXPR is supposed to point
#define OMP_CLAUSE_FIRSTPRIVATE_IMPLICIT(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FIRSTPRIVATE)->base.public_flag)
+/* True on a FIRSTPRIVATE clause if only the reference and not what it refers
+ to should be firstprivatized. */
+#define OMP_CLAUSE_FIRSTPRIVATE_NO_REFERENCE(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_FIRSTPRIVATE))
+
/* 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_LASTPRIVATE_GIMPLE_SEQ(NODE) \
(OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
-/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop construct
- (thus should be lastprivate on the outer taskloop and firstprivate on
- task). */
-#define OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV(NODE) \
+/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop or
+ loop construct (thus should be lastprivate on the outer taskloop and
+ firstprivate on task for the taskloop construct and carefully handled
+ for loop construct). */
+#define OMP_CLAUSE_LASTPRIVATE_LOOP_IV(NODE) \
TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE))
+/* True if a LASTPRIVATE clause has CONDITIONAL: modifier. */
+#define OMP_CLAUSE_LASTPRIVATE_CONDITIONAL(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE))
+
/* True on a SHARED clause if a FIRSTPRIVATE clause for the same
decl is present in the chain (this can happen only for taskloop
with FIRSTPRIVATE/LASTPRIVATE on it originally. */
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. */
+/* Nonzero if this map clause is for an OpenACC compute construct's reduction
+ variable. */
#define OMP_CLAUSE_MAP_IN_REDUCTION(NODE) \
TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP))
+/* True on an OMP_CLAUSE_USE_DEVICE_PTR with an OpenACC 'if_present'
+ clause. */
+#define OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_USE_DEVICE_PTR)->base.public_flag)
+
#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_DEVICE_TYPE_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE_TYPE)->omp_clause.subcode.device_type_kind)
+
#define OMP_CLAUSE_COLLAPSE_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_COLLAPSE), 0)
#define OMP_CLAUSE_COLLAPSE_ITERVAR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ORDERED), 0)
#define OMP_CLAUSE_REDUCTION_CODE(NODE) \
- (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)->omp_clause.subcode.reduction_code)
+ (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
+ OMP_CLAUSE_IN_REDUCTION)->omp_clause.subcode.reduction_code)
#define OMP_CLAUSE_REDUCTION_INIT(NODE) \
- OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 1)
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
+ OMP_CLAUSE_IN_REDUCTION), 1)
#define OMP_CLAUSE_REDUCTION_MERGE(NODE) \
- OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 2)
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
+ OMP_CLAUSE_IN_REDUCTION), 2)
#define OMP_CLAUSE_REDUCTION_GIMPLE_INIT(NODE) \
(OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
#define OMP_CLAUSE_REDUCTION_GIMPLE_MERGE(NODE) \
(OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_merge
#define OMP_CLAUSE_REDUCTION_PLACEHOLDER(NODE) \
- OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 3)
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
+ OMP_CLAUSE_IN_REDUCTION), 3)
#define OMP_CLAUSE_REDUCTION_DECL_PLACEHOLDER(NODE) \
- OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 4)
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
+ OMP_CLAUSE_IN_REDUCTION), 4)
/* True if a REDUCTION clause may reference the original list item (omp_orig)
in its OMP_CLAUSE_REDUCTION_{,GIMPLE_}INIT. */
#define OMP_CLAUSE_REDUCTION_OMP_ORIG_REF(NODE) \
- (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION)->base.public_flag)
+ (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_REDUCTION, \
+ OMP_CLAUSE_IN_REDUCTION)->base.public_flag)
+
+/* True if a REDUCTION clause has task reduction-modifier. */
+#define OMP_CLAUSE_REDUCTION_TASK(NODE) \
+ TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION))
+
+/* True if a REDUCTION clause has inscan reduction-modifier. */
+#define OMP_CLAUSE_REDUCTION_INSCAN(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION))
/* True if a LINEAR clause doesn't need copy in. True for iterator vars which
are always initialized inside of the loop construct, false otherwise. */
#define OMP_CLAUSE_DEFAULT_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind)
+#define OMP_CLAUSE_DEFAULTMAP_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULTMAP)->omp_clause.subcode.defaultmap_kind)
+#define OMP_CLAUSE_DEFAULTMAP_CATEGORY(NODE) \
+ ((enum omp_clause_defaultmap_kind) \
+ (OMP_CLAUSE_DEFAULTMAP_KIND (NODE) & OMP_CLAUSE_DEFAULTMAP_CATEGORY_MASK))
+#define OMP_CLAUSE_DEFAULTMAP_BEHAVIOR(NODE) \
+ ((enum omp_clause_defaultmap_kind) \
+ (OMP_CLAUSE_DEFAULTMAP_KIND (NODE) & OMP_CLAUSE_DEFAULTMAP_MASK))
+#define OMP_CLAUSE_DEFAULTMAP_SET_KIND(NODE, BEHAVIOR, CATEGORY) \
+ (OMP_CLAUSE_DEFAULTMAP_KIND (NODE) \
+ = (enum omp_clause_defaultmap_kind) (CATEGORY | BEHAVIOR))
+
+#define OMP_CLAUSE_BIND_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_BIND)->omp_clause.subcode.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) \
#define OMP_CLAUSE__GRIDDIM__GROUP(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__GRIDDIM_), 1)
+/* _CONDTEMP_ holding temporary with iteration count. */
+#define OMP_CLAUSE__CONDTEMP__ITER(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__CONDTEMP_)->base.public_flag)
+
+/* _SCANTEMP_ holding temporary with pointer to thread's local array;
+ allocation. */
+#define OMP_CLAUSE__SCANTEMP__ALLOC(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SCANTEMP_)->base.public_flag)
+
+/* _SCANTEMP_ holding temporary with a control variable for deallocation;
+ one boolean_type_node for test whether alloca was used, another one
+ to pass to __builtin_stack_restore or free. */
+#define OMP_CLAUSE__SCANTEMP__CONTROL(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SCANTEMP_))
+
/* SSA_NAME accessors. */
/* Whether SSA_NAME NODE is a virtual operand. This simply caches the
#define SSA_NAME_IS_DEFAULT_DEF(NODE) \
SSA_NAME_CHECK (NODE)->base.default_def_flag
+/* Nonzero if this SSA_NAME is known to point to memory that may not
+ be written to. This is set for default defs of function parameters
+ that have a corresponding r or R specification in the functions
+ fn spec attribute. This is used by alias analysis. */
+#define SSA_NAME_POINTS_TO_READONLY_MEMORY(NODE) \
+ SSA_NAME_CHECK (NODE)->base.deprecated_flag
+
/* Attributes for SSA_NAMEs for pointer-type variables. */
#define SSA_NAME_PTR_INFO(N) \
SSA_NAME_CHECK (N)->ssa_name.info.ptr_info
#define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
#define BLOCK_CHAIN(NODE) (BLOCK_CHECK (NODE)->block.chain)
#define BLOCK_ABSTRACT_ORIGIN(NODE) (BLOCK_CHECK (NODE)->block.abstract_origin)
-#define BLOCK_ABSTRACT(NODE) (BLOCK_CHECK (NODE)->block.abstract_flag)
+#define BLOCK_ORIGIN(NODE) \
+ (BLOCK_ABSTRACT_ORIGIN(NODE) ? BLOCK_ABSTRACT_ORIGIN(NODE) : (NODE))
#define BLOCK_DIE(NODE) (BLOCK_CHECK (NODE)->block.die)
/* True if BLOCK has the same ranges as its BLOCK_SUPERCONTEXT. */
so they must be checked as well. */
#define TYPE_UID(NODE) (TYPE_CHECK (NODE)->type_common.uid)
+/* Type size in bits as a tree expression. Need not be constant
+ and may be null. */
#define TYPE_SIZE(NODE) (TYPE_CHECK (NODE)->type_common.size)
+/* Likewise, type size in bytes. */
#define TYPE_SIZE_UNIT(NODE) (TYPE_CHECK (NODE)->type_common.size_unit)
#define TYPE_POINTER_TO(NODE) (TYPE_CHECK (NODE)->type_common.pointer_to)
#define TYPE_REFERENCE_TO(NODE) (TYPE_CHECK (NODE)->type_common.reference_to)
extern machine_mode element_mode (const_tree);
extern machine_mode vector_type_mode (const_tree);
+extern unsigned int vector_element_bits (const_tree);
+extern tree vector_element_bits_tree (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
/* If set in an ARRAY_TYPE, indicates a string type (for languages
that distinguish string from array of char).
If set in a INTEGER_TYPE, indicates a character type. */
-#define TYPE_STRING_FLAG(NODE) (TYPE_CHECK (NODE)->type_common.string_flag)
+#define TYPE_STRING_FLAG(NODE) \
+ (ARRAY_OR_INTEGER_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) \
- (HOST_WIDE_INT_1U \
- << 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))
+/* If set for RECORD_TYPE or UNION_TYPE it indicates that the type conforms
+ to the C++ one definition rule. This is used for LTO canonical type
+ computation. */
+#define TYPE_CXX_ODR_P(NODE) \
+ (RECORD_OR_UNION_CHECK (NODE)->type_common.string_flag)
/* Nonzero in a VECTOR_TYPE if the frontends should not emit warnings
about missing conversions to other vector types of the same size. */
#define DECL_IS_BUILTIN(DECL) \
(LOCATION_LOCUS (DECL_SOURCE_LOCATION (DECL)) <= BUILTINS_LOCATION)
-#define DECL_LOCATION_RANGE(NODE) \
- (get_decl_source_range (DECL_MINIMAL_CHECK (NODE)))
-
/* For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
PARM_DECL, FUNCTION_DECL, LABEL_DECL, RESULT_DECL, and CONST_DECL
#define DECL_INITIAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.initial)
/* Holds the size of the datum, in bits, as a tree expression.
- Need not be constant. */
+ Need not be constant and may be null. */
#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)
(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
- DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be
- checked before any access to the former. */
-#define DECL_FUNCTION_CODE(NODE) \
+ operation it is. This is only intended for low-level accesses;
+ normally DECL_FUNCTION_CODE, DECL_FE_FUNCTION_CODE or DECL_MD_FUNCTION
+ should be used instead. */
+#define DECL_UNCHECKED_FUNCTION_CODE(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.function_code)
/* Test if FCODE is a function code for an alloca operation. */
they are killing assignments. Thus the variable may now
be treated as a GIMPLE register, and use real instead of
virtual ops in SSA form. */
-#define DECL_GIMPLE_REG_P(DECL) \
- DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag
+#define DECL_NOT_GIMPLE_REG_P(DECL) \
+ DECL_COMMON_CHECK (DECL)->decl_common.not_gimple_reg_flag
extern tree decl_value_expr_lookup (tree);
extern void decl_value_expr_insert (tree, tree);
/* In a FIELD_DECL, indicates this field should be bit-packed. */
#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->base.u.bits.packed_flag)
+/* In a FIELD_DECL, indicates this field should be ignored for ABI decisions
+ like passing/returning containing struct by value.
+ Set for C++17 empty base artificial FIELD_DECLs as well as
+ empty [[no_unique_address]] non-static data members. */
+#define DECL_FIELD_ABI_IGNORED(NODE) \
+ (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_0)
+
/* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
specially. */
#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_1)
#define DECL_VISIBILITY(NODE) \
(DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility)
-/* Nonzero means that the decl had its visibility specified rather than
- being inferred. */
+/* Nonzero means that the decl (or an enclosing scope) had its
+ visibility specified rather than being inferred. */
#define DECL_VISIBILITY_SPECIFIED(NODE) \
(DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.visibility_specified)
#define DECL_IS_MALLOC(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.malloc_flag)
+/* Macro for direct set and get of function_decl.decl_type. */
+#define FUNCTION_DECL_DECL_TYPE(NODE) \
+ (NODE->function_decl.decl_type)
+
+/* Set decl_type of a DECL. Set it to T when SET is true, or reset
+ it to NONE. */
+
+static inline void
+set_function_decl_type (tree decl, function_decl_type t, bool set)
+{
+ if (set)
+ {
+ gcc_assert (FUNCTION_DECL_DECL_TYPE (decl) == NONE
+ || FUNCTION_DECL_DECL_TYPE (decl) == t);
+ decl->function_decl.decl_type = t;
+ }
+ else if (FUNCTION_DECL_DECL_TYPE (decl) == t)
+ FUNCTION_DECL_DECL_TYPE (decl) = NONE;
+}
+
+/* Nonzero in a FUNCTION_DECL means this function is a replaceable
+ function (like replaceable operators new or delete). */
+#define DECL_IS_REPLACEABLE_OPERATOR(NODE)\
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.replaceable_operator)
+
/* Nonzero in a FUNCTION_DECL means this function should be treated as
C++ operator new, meaning that it returns a pointer for which we
should not use type based aliasing. */
-#define DECL_IS_OPERATOR_NEW(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->function_decl.operator_new_flag)
+#define DECL_IS_OPERATOR_NEW_P(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_NEW)
+
+#define DECL_IS_REPLACEABLE_OPERATOR_NEW_P(NODE) \
+ (DECL_IS_OPERATOR_NEW_P (NODE) && DECL_IS_REPLACEABLE_OPERATOR (NODE))
+
+#define DECL_SET_IS_OPERATOR_NEW(NODE, VAL) \
+ set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_NEW, VAL)
+
+/* Nonzero in a FUNCTION_DECL means this function should be treated as
+ C++ operator delete. */
+#define DECL_IS_OPERATOR_DELETE_P(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_DELETE)
+
+#define DECL_IS_REPLACEABLE_OPERATOR_DELETE_P(NODE) \
+ (DECL_IS_OPERATOR_DELETE_P (NODE) && DECL_IS_REPLACEABLE_OPERATOR (NODE))
+
+#define DECL_SET_IS_OPERATOR_DELETE(NODE, VAL) \
+ set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_DELETE, VAL)
/* Nonzero in a FUNCTION_DECL means this function may return more
than once. */
#define DECL_STRUCT_FUNCTION(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.f)
-/* In a FUNCTION_DECL, nonzero means a built in function of a
- standard library or more generally a built in function that is
- recognized by optimizers and expanders.
-
- Note that it is different from the DECL_IS_BUILTIN accessor. For
- instance, user declared prototypes of C library functions are not
- DECL_IS_BUILTIN but may be DECL_BUILT_IN. */
-#define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN)
-
/* For a builtin function, identify which part of the compiler defined it. */
#define DECL_BUILT_IN_CLASS(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
+ ((built_in_class) FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
/* In FUNCTION_DECL, a chain of ..._DECL nodes. */
#define DECL_ARGUMENTS(NODE) \
#define DECL_CXX_DESTRUCTOR_P(NODE)\
(FUNCTION_DECL_CHECK (NODE)->decl_with_vis.cxx_destructor)
+/* In FUNCTION_DECL, this is set if this function is a lambda function. */
+#define DECL_LAMBDA_FUNCTION_P(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == LAMBDA_FUNCTION)
+
+#define DECL_SET_LAMBDA_FUNCTION(NODE, VAL) \
+ set_function_decl_type (FUNCTION_DECL_CHECK (NODE), LAMBDA_FUNCTION, VAL)
+
/* In FUNCTION_DECL that represent an virtual method this is set when
the method is final. */
#define DECL_FINAL_P(NODE)\
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)
+ {
+ /* See the corresponding code in SET_TYPE_VECTOR_SUBPARTS for a
+ description of the encoding. */
+ poly_uint64 res = 0;
+ res.coeffs[0] = HOST_WIDE_INT_1U << (precision & 0xff);
+ if (precision & 0x100)
+ res.coeffs[1] = HOST_WIDE_INT_1U << (precision & 0xff);
+ return res;
+ }
+ else
+ return HOST_WIDE_INT_1U << 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)
+ {
+ /* We have two coefficients that are each in the range 1 << [0, 63],
+ so supporting all combinations would require 6 bits per coefficient
+ and 12 bits in total. Since the precision field is only 10 bits
+ in size, we need to be more restrictive than that.
+
+ At present, coeff[1] is always either 0 (meaning that the number
+ of units is constant) or equal to coeff[0] (meaning that the number
+ of units is N + X * N for some target-dependent zero-based runtime
+ parameter X). We can therefore encode coeff[1] in a single bit.
+
+ The most compact encoding would be to use mask 0x3f for coeff[0]
+ and 0x40 for coeff[1], leaving 0x380 unused. It's possible to
+ get slightly more efficient code on some hosts if we instead
+ treat the shift amount as an independent byte, so here we use
+ 0xff for coeff[0] and 0x100 for coeff[1]. */
+ 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;
+}
+
+/* Return the built-in function that DECL represents, given that it is known
+ to be a FUNCTION_DECL with built-in class BUILT_IN_NORMAL. */
+inline built_in_function
+DECL_FUNCTION_CODE (const_tree decl)
+{
+ const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ gcc_checking_assert (fndecl.built_in_class == BUILT_IN_NORMAL);
+ return (built_in_function) fndecl.function_code;
+}
+
+/* Return the target-specific built-in function that DECL represents,
+ given that it is known to be a FUNCTION_DECL with built-in class
+ BUILT_IN_MD. */
+inline int
+DECL_MD_FUNCTION_CODE (const_tree decl)
+{
+ const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ gcc_checking_assert (fndecl.built_in_class == BUILT_IN_MD);
+ return fndecl.function_code;
+}
+
+/* Return the frontend-specific built-in function that DECL represents,
+ given that it is known to be a FUNCTION_DECL with built-in class
+ BUILT_IN_FRONTEND. */
+inline int
+DECL_FE_FUNCTION_CODE (const_tree decl)
+{
+ const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ gcc_checking_assert (fndecl.built_in_class == BUILT_IN_FRONTEND);
+ return fndecl.function_code;
+}
+
+/* Record that FUNCTION_DECL DECL represents built-in function FCODE of
+ class FCLASS. */
+inline void
+set_decl_built_in_function (tree decl, built_in_class fclass,
+ unsigned int fcode)
+{
+ tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ fndecl.built_in_class = fclass;
+ fndecl.function_code = fcode;
+}
+
+/* Record that FUNCTION_DECL NEWDECL represents the same built-in function
+ as OLDDECL (or none, if OLDDECL doesn't represent a built-in function). */
+inline void
+copy_decl_built_in_function (tree newdecl, const_tree olddecl)
+{
+ tree_function_decl &newfndecl = FUNCTION_DECL_CHECK (newdecl)->function_decl;
+ const tree_function_decl &oldfndecl
+ = FUNCTION_DECL_CHECK (olddecl)->function_decl;
+ newfndecl.built_in_class = oldfndecl.built_in_class;
+ newfndecl.function_code = oldfndecl.function_code;
+}
+
+/* In NON_LVALUE_EXPR and VIEW_CONVERT_EXPR, set when this node is merely a
+ wrapper added to express a location_t on behalf of the node's child
+ (e.g. by maybe_wrap_with_location). */
+
+#define EXPR_LOCATION_WRAPPER_P(NODE) \
+ (TREE_CHECK2(NODE, NON_LVALUE_EXPR, VIEW_CONVERT_EXPR)->base.public_flag)
+
+/* Test if EXP is merely a wrapper node, added to express a location_t
+ on behalf of the node's child (e.g. by maybe_wrap_with_location). */
+
+inline bool
+location_wrapper_p (const_tree exp)
+{
+ /* A wrapper node has code NON_LVALUE_EXPR or VIEW_CONVERT_EXPR, and
+ the flag EXPR_LOCATION_WRAPPER_P is set.
+ It normally has the same type as its operand, but it can have a
+ different one if the type of the operand has changed (e.g. when
+ merging duplicate decls).
+
+ NON_LVALUE_EXPR is used for wrapping constants, apart from STRING_CST.
+ VIEW_CONVERT_EXPR is used for wrapping non-constants and STRING_CST. */
+ if ((TREE_CODE (exp) == NON_LVALUE_EXPR
+ || TREE_CODE (exp) == VIEW_CONVERT_EXPR)
+ && EXPR_LOCATION_WRAPPER_P (exp))
+ return true;
+ return false;
+}
+
+/* Implementation of STRIP_ANY_LOCATION_WRAPPER. */
+
+inline tree
+tree_strip_any_location_wrapper (tree exp)
+{
+ if (location_wrapper_p (exp))
+ return TREE_OPERAND (exp, 0);
+ else
+ return exp;
+}
+
#define error_mark_node global_trees[TI_ERROR_MARK]
#define intQI_type_node global_trees[TI_INTQI_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]
/* The C type `void *'. */
#define ptr_type_node global_trees[TI_PTR_TYPE]
#define dfloat32_type_node global_trees[TI_DFLOAT32_TYPE]
#define dfloat64_type_node global_trees[TI_DFLOAT64_TYPE]
#define dfloat128_type_node global_trees[TI_DFLOAT128_TYPE]
-#define dfloat32_ptr_type_node global_trees[TI_DFLOAT32_PTR_TYPE]
-#define dfloat64_ptr_type_node global_trees[TI_DFLOAT64_PTR_TYPE]
-#define dfloat128_ptr_type_node global_trees[TI_DFLOAT128_PTR_TYPE]
/* The fixed-point types. */
#define sat_short_fract_type_node global_trees[TI_SAT_SFRACT_TYPE]
#define current_target_pragma global_trees[TI_CURRENT_TARGET_PRAGMA]
#define current_optimize_pragma global_trees[TI_CURRENT_OPTIMIZE_PRAGMA]
+/* SCEV analyzer global shared trees. */
+#define chrec_not_analyzed_yet NULL_TREE
+#define chrec_dont_know global_trees[TI_CHREC_DONT_KNOW]
+#define chrec_known global_trees[TI_CHREC_KNOWN]
+
#define char_type_node integer_types[itk_char]
#define signed_char_type_node integer_types[itk_signed_char]
#define unsigned_char_type_node integer_types[itk_unsigned_char]
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 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_uniform_cst (tree, tree);
+extern tree build_vec_series (tree, tree, tree);
+extern tree build_index_vector (tree, poly_uint64, poly_uint64);
+extern tree build_vector_a_then_b (tree, unsigned int, tree, tree);
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 (tree, vec<constructor_elt, va_gc> * CXX_MEM_STAT_INFO);
extern tree build_constructor_single (tree, tree, tree);
extern tree build_constructor_from_list (tree, tree);
extern tree build_constructor_va (tree, int, ...);
+extern tree build_clobber (tree);
extern tree build_real_from_int_cst (tree, const_tree);
extern tree build_complex (tree, tree, tree);
extern tree build_complex_inf (tree, bool);
extern tree build_all_ones_cst (tree);
extern tree build_zero_cst (tree);
extern tree build_string (int, const char *);
+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,
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 *);
+extern tree build_string_literal (int, const char *, tree = char_type_node,
+ unsigned HOST_WIDE_INT = HOST_WIDE_INT_M1U);
/* 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_same_sized_truth_vector_type (tree vectype);
-extern tree build_opaque_vector_type (tree innertype, int nunits);
+extern tree build_vector_type (tree, poly_int64);
+extern tree build_truth_vector_type_for_mode (poly_uint64, machine_mode);
+extern tree build_opaque_vector_type (tree, poly_int64);
extern tree build_index_type (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 bool vec_member (const_tree, vec<tree, va_gc> *);
extern tree chain_index (int, tree);
+/* Arguments may be null. */
extern int tree_int_cst_equal (const_tree, const_tree);
-extern bool tree_fits_shwi_p (const_tree)
- ATTRIBUTE_PURE;
-extern bool tree_fits_uhwi_p (const_tree)
- ATTRIBUTE_PURE;
-extern HOST_WIDE_INT tree_to_shwi (const_tree);
-extern unsigned HOST_WIDE_INT tree_to_uhwi (const_tree);
+/* The following predicates are safe to call with a null argument. */
+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)
+ ATTRIBUTE_NONNULL (1) ATTRIBUTE_PURE;
+extern poly_int64 tree_to_poly_int64 (const_tree)
+ ATTRIBUTE_NONNULL (1) ATTRIBUTE_PURE;
+extern unsigned HOST_WIDE_INT tree_to_uhwi (const_tree)
+ ATTRIBUTE_NONNULL (1) ATTRIBUTE_PURE;
+extern poly_uint64 tree_to_poly_uint64 (const_tree)
+ ATTRIBUTE_NONNULL (1) ATTRIBUTE_PURE;
#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 unsigned int tree_int_cst_min_precision (tree, signop);
extern tree strip_array_types (tree);
extern tree excess_precision_type (tree);
-extern bool valid_constant_size_p (const_tree);
+/* Desription of the reason why the argument of valid_constant_size_p
+ is not a valid size. */
+enum cst_size_error {
+ cst_size_ok,
+ cst_size_not_constant,
+ cst_size_negative,
+ cst_size_too_big,
+ cst_size_overflow
+};
+
+extern bool valid_constant_size_p (const_tree, cst_size_error * = NULL);
+extern tree max_object_size ();
+
+/* 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. */
+
+inline bool
+poly_int_tree_p (const_tree t, poly_int64_pod *value)
+{
+ 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. */
+
+inline bool
+poly_int_tree_p (const_tree t, poly_uint64_pod *value)
+{
+ if (tree_fits_poly_uint64_p (t))
+ {
+ *value = tree_to_poly_uint64 (t);
+ return true;
+ }
+ return false;
+}
/* 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
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_loc (location_t, const_tree);
inline tree
size_in_bytes (const_tree t)
extern int list_length (const_tree);
-/* Returns the first FIELD_DECL in a type. */
+/* Returns the first/last FIELD_DECL in a RECORD_TYPE. */
-extern tree first_field (const_tree);
+extern tree first_field (const_tree) ATTRIBUTE_NONNULL (1);
+extern tree last_field (const_tree) ATTRIBUTE_NONNULL (1);
/* Given an initializer INIT, return TRUE if INIT is zero or some
- aggregate of zeros. Otherwise return FALSE. */
+ aggregate of zeros. Otherwise return FALSE. If NONZERO is not
+ null, set *NONZERO if and only if INIT is known not to be all
+ zeros. The combination of return value of false and *NONZERO
+ false implies that INIT may but need not be all zeros. Other
+ combinations indicate definitive answers. */
-extern bool initializer_zerop (const_tree);
+extern bool initializer_zerop (const_tree, bool * = NULL);
+extern bool initializer_each_zero_or_onep (const_tree);
extern wide_int vector_cst_int_elt (const_tree, unsigned int);
extern tree vector_cst_elt (const_tree, unsigned int);
extern tree uniform_vector_p (const_tree);
+/* If the argument is INTEGER_CST, return it. If the argument is vector
+ with all elements the same INTEGER_CST, return that INTEGER_CST. Otherwise
+ return NULL_TREE. */
+
+extern tree uniform_integer_cst_p (tree);
+
+extern int single_nonzero_element (const_tree);
+
/* Given a CONSTRUCTOR CTOR, return the element values as a vector. */
extern vec<tree, va_gc> *ctor_to_vec (tree);
/* zerop (tree x) is nonzero if X is a constant of value 0. */
-extern int zerop (const_tree);
+extern bool zerop (const_tree);
/* integer_zerop (tree x) is nonzero if X is an integer constant of value 0. */
-extern int integer_zerop (const_tree);
+extern bool integer_zerop (const_tree);
/* integer_onep (tree x) is nonzero if X is an integer constant of value 1. */
-extern int integer_onep (const_tree);
+extern bool integer_onep (const_tree);
/* integer_onep (tree x) is nonzero if X is an integer constant of value 1, or
a vector or complex where each part is 1. */
-extern int integer_each_onep (const_tree);
+extern bool integer_each_onep (const_tree);
/* integer_all_onesp (tree x) is nonzero if X is an integer constant
all of whose significant bits are 1. */
-extern int integer_all_onesp (const_tree);
+extern bool integer_all_onesp (const_tree);
/* integer_minus_onep (tree x) is nonzero if X is an integer constant of
value -1. */
-extern int integer_minus_onep (const_tree);
+extern bool integer_minus_onep (const_tree);
/* integer_pow2p (tree x) is nonzero is X is an integer constant with
exactly one bit 1. */
-extern int integer_pow2p (const_tree);
+extern bool integer_pow2p (const_tree);
/* integer_nonzerop (tree x) is nonzero if X is an integer constant
with a nonzero value. */
-extern int integer_nonzerop (const_tree);
+extern bool integer_nonzerop (const_tree);
/* integer_truep (tree x) is nonzero if X is an integer constant of value 1 or
a vector where each element is an integer constant of value -1. */
-extern int integer_truep (const_tree);
+extern bool integer_truep (const_tree);
extern bool cst_and_fits_in_hwi (const_tree);
extern tree num_ending_zeros (const_tree);
/* fixed_zerop (tree x) is nonzero if X is a fixed-point constant of
value 0. */
-extern int fixed_zerop (const_tree);
+extern bool fixed_zerop (const_tree);
/* staticp (tree x) is nonzero if X is a reference to data allocated
at a fixed address in memory. Returns the outermost data. */
this _DECL with its context, or zero if none. */
extern tree decl_type_context (const_tree);
-/* Return 1 if EXPR is the real constant zero. */
-extern int real_zerop (const_tree);
+/* Return true if EXPR is the real constant zero. */
+extern bool real_zerop (const_tree);
/* Initialize the iterator I with arguments from function FNDECL */
extern tree get_callee_fndecl (const_tree);
extern combined_fn get_call_combined_fn (const_tree);
extern int type_num_arguments (const_tree);
+extern tree type_argument_type (const_tree, unsigned) ATTRIBUTE_NONNULL (1);
extern bool associative_tree_code (enum tree_code);
extern bool commutative_tree_code (enum tree_code);
extern bool commutative_ternary_tree_code (enum tree_code);
extern bool prototype_p (const_tree);
extern bool is_typedef_decl (const_tree x);
extern bool typedef_variant_p (const_tree);
+extern bool auto_var_p (const_tree);
extern bool auto_var_in_fn_p (const_tree, const_tree);
extern tree build_low_bits_mask (tree, unsigned);
extern bool tree_nop_conversion_p (const_tree, const_tree);
extern const_tree strip_invariant_refs (const_tree);
extern tree lhd_gcc_personality (void);
extern void assign_assembler_name_if_needed (tree);
-extern void warn_deprecated_use (tree, tree);
+extern bool warn_deprecated_use (tree, tree);
extern void cache_integer_cst (tree);
extern const char *combined_fn_name (combined_fn);
&& 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 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);
+extern bool int_fits_type_p (const_tree, const_tree)
+ ATTRIBUTE_NONNULL (1) ATTRIBUTE_NONNULL (2) ATTRIBUTE_PURE;
#ifndef GENERATOR_FILE
extern void get_type_static_bounds (const_tree, mpz_t, mpz_t);
#endif
}
extern int compare_tree_int (const_tree, unsigned HOST_WIDE_INT);
-extern int type_list_equal (const_tree, const_tree);
-extern int chain_member (const_tree, const_tree);
+extern bool type_list_equal (const_tree, const_tree);
+extern bool chain_member (const_tree, const_tree);
extern void dump_tree_statistics (void);
extern void recompute_tree_invariant_for_addr_expr (tree);
extern bool needs_to_live_in_memory (const_tree);
extern tree reconstruct_complex_type (tree, tree);
-extern int real_onep (const_tree);
-extern int real_minus_onep (const_tree);
+extern bool real_onep (const_tree);
+extern bool real_minus_onep (const_tree);
extern void init_ttree (void);
extern void build_common_tree_nodes (bool);
extern void build_common_builtin_nodes (void);
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,
- bool strict=false);
+extern bool types_same_for_odr (const_tree type1, const_tree type2);
extern bool contains_bitfld_component_ref_p (const_tree);
extern bool block_may_fallthru (const_tree);
extern void using_eh_for_cleanups (void);
of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
extern tree array_ref_element_size (tree);
+/* Return a typenode for the "standard" C type with a given name. */
+extern tree get_typenode_from_name (const char *);
+
/* Return a tree representing the upper bound of the array mentioned in
EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
extern tree array_ref_up_bound (tree);
by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
extern tree component_ref_field_offset (tree);
+/* Return the size of the member referenced by the COMPONENT_REF, using
+ its initializer expression if necessary in order to determine the size
+ of an initialized flexible array member. The size might be zero for
+ an object with an uninitialized flexible array member or null if it
+ cannot be determined. */
+extern tree component_ref_size (tree, bool * = NULL);
+
extern int tree_map_base_eq (const void *, const void *);
extern unsigned int tree_map_base_hash (const void *);
extern int tree_map_base_marked_p (const void *);
#define tree_vec_map_hash tree_decl_map_hash
#define tree_vec_map_marked_p tree_map_base_marked_p
+/* Hasher for tree decls. Pointer equality is enough here, but the DECL_UID
+ is a better hash than the pointer value and gives a predictable traversal
+ order. Additionally it can be used across PCH save/restore. */
+struct tree_decl_hash : ggc_ptr_hash <tree_node>
+{
+ static inline hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_decl_hash::hash (tree t)
+{
+ return DECL_UID (t);
+}
+
+/* Similarly for types. Uses TYPE_UID as hash function. */
+struct tree_type_hash : ggc_ptr_hash <tree_node>
+{
+ static inline hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_type_hash::hash (tree t)
+{
+ return TYPE_UID (t);
+}
+
+/* Hash for SSA_NAMEs in the same function. Pointer equality is enough
+ here, but the SSA_NAME_VERSION is a better hash than the pointer
+ value and gives a predictable traversal order. */
+struct tree_ssa_name_hash : ggc_ptr_hash <tree_node>
+{
+ static inline hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_ssa_name_hash::hash (tree t)
+{
+ return SSA_NAME_VERSION (t);
+}
+
+/* Hasher for general trees, based on their TREE_HASH. */
+struct tree_hash : ggc_ptr_hash <tree_node>
+{
+ static hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_hash::hash (tree t)
+{
+ return TREE_HASH (t);
+}
+
/* 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. */
: simple_cache_map_traits<default_hash_traits<tree>, tree> { };
typedef hash_map<tree,tree,tree_cache_traits> tree_cache_map;
+/* Similarly, but use DECL_UID as hash function rather than pointer hashing.
+ This is for hash_maps from decls to trees that need to work across PCH. */
+struct decl_tree_cache_traits
+ : simple_cache_map_traits<tree_decl_hash, tree> { };
+typedef hash_map<tree,tree,decl_tree_cache_traits> decl_tree_cache_map;
+
+/* Similarly, but use TYPE_UID as hash function rather than pointer hashing.
+ This is for hash_maps from types to trees that need to work across PCH. */
+struct type_tree_cache_traits
+ : simple_cache_map_traits<tree_type_hash, tree> { };
+typedef hash_map<tree,tree,type_tree_cache_traits> type_tree_cache_map;
+
/* Initialize the abstract argument list iterator object ITER with the
arguments from CALL_EXPR node EXP. */
static inline void
&& builtin_info[uns_fncode].declared_p);
}
+/* Determine if the function identified by FNDECL is one that
+ makes sense to match by name, for those places where we detect
+ "magic" functions by name.
+
+ Return true if FNDECL has a name and is an extern fndecl at file scope.
+ FNDECL must be a non-NULL decl.
+
+ Avoid using this, as it's generally better to use attributes rather
+ than to check for functions by name. */
+
+static inline bool
+maybe_special_function_p (const_tree fndecl)
+{
+ tree name_decl = DECL_NAME (fndecl);
+ if (name_decl
+ /* Exclude functions not at the file scope, or not `extern',
+ since they are not the magic functions we would otherwise
+ think they are. */
+ && (DECL_CONTEXT (fndecl) == NULL_TREE
+ || TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL)
+ && TREE_PUBLIC (fndecl))
+ return true;
+ return false;
+}
+
/* Return true if T (assumed to be a DECL) is a global variable.
A variable is considered global if its storage is not automatic. */
|| DECL_EXTERNAL (var)
|| TREE_ADDRESSABLE (var))
&& !((TREE_STATIC (var) || TREE_PUBLIC (var) || DECL_EXTERNAL (var))
- && ((TREE_READONLY (var)
- && !TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var)))
+ && (TREE_READONLY (var)
|| (TREE_CODE (var) == VAR_DECL
&& DECL_NONALIASED (var)))));
}
/* For anonymous aggregate types, we need some sort of name to
hold on to. In practice, this should not appear, but it should
- not be harmful if it does. */
-extern const char *anon_aggrname_format();
-extern bool anon_aggrname_p (const_tree);
+ not be harmful if it does. Identifiers returned will be
+ IDENTIFIER_ANON_P. */
+extern tree make_anon_name ();
/* 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 <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;
+ };
+
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;
};
- typedef const generic_wide_int <extended_tree <WIDE_INT_MAX_PRECISION> >
- tree_to_widest_ref;
- typedef const generic_wide_int <extended_tree <ADDR_MAX_PRECISION> >
- tree_to_offset_ref;
+ 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_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);
+
+ 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 &);
+ };
+
+ template <>
+ struct ints_for <generic_wide_int <unextended_tree>, VAR_PRECISION>
+ {
+ typedef generic_wide_int <unextended_tree> unextended;
+ static unextended zero (const unextended &);
+ };
}
+/* Used to convert a tree to a widest2_int like this:
+ widest2_int foo = widest2_int_cst (some_tree). */
+typedef generic_wide_int <wi::extended_tree <WIDE_INT_MAX_PRECISION * 2> >
+ widest2_int_cst;
+
/* Refer to INTEGER_CST T as though it were a widest_int.
This function gives T's actual numerical value, influenced by the
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
wi::fits_to_boolean_p (const T &x, const_tree type)
{
- return eq_p (x, 0) || eq_p (x, TYPE_UNSIGNED (type) ? 1 : -1);
+ 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>
return fits_to_boolean_p (x, type);
if (TYPE_UNSIGNED (type))
- return eq_p (x, zext (x, TYPE_PRECISION (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
/* 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 *,
+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 *);
if (COMPLETE_TYPE_P (t))
return true;
- /* Incomplete types can not be accessed in general except for arrays
+ /* Incomplete types cannot be accessed in general except for arrays
where we can fetch its element despite we have no array bounds. */
if (TREE_CODE (t) == ARRAY_TYPE && COMPLETE_TYPE_P (TREE_TYPE (t)))
return true;
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 bool flexible_array_type_p (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 location_t
set_source_range (tree expr, source_range src_range);
-static inline source_range
-get_decl_source_range (tree decl)
-{
- location_t loc = DECL_SOURCE_LOCATION (decl);
- 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)
/* Pointer type used to declare builtins before we have seen its real
declaration. */
-struct builtin_structptr_type
+class builtin_structptr_type
{
+public:
tree& node;
tree& base;
const char *str;
inline bool
type_has_mode_precision_p (const_tree t)
{
- return TYPE_PRECISION (t) == GET_MODE_PRECISION (TYPE_MODE (t));
+ return known_eq (TYPE_PRECISION (t), GET_MODE_PRECISION (TYPE_MODE (t)));
+}
+
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function.
+
+ Note that it is different from the DECL_IS_BUILTIN accessor. For
+ instance, user declared prototypes of C library functions are not
+ DECL_IS_BUILTIN but may be fndecl_built_in_p. */
+
+inline bool
+fndecl_built_in_p (const_tree node)
+{
+ return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
+}
+
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
+ of class KLASS. */
+
+inline bool
+fndecl_built_in_p (const_tree node, built_in_class klass)
+{
+ return fndecl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass;
+}
+
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
+ of class KLASS with name equal to NAME. */
+
+inline bool
+fndecl_built_in_p (const_tree node, unsigned int name, built_in_class klass)
+{
+ return (fndecl_built_in_p (node, klass)
+ && DECL_UNCHECKED_FUNCTION_CODE (node) == name);
+}
+
+/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
+ of BUILT_IN_NORMAL class with name equal to NAME. */
+
+inline bool
+fndecl_built_in_p (const_tree node, built_in_function name)
+{
+ return (fndecl_built_in_p (node, BUILT_IN_NORMAL)
+ && DECL_FUNCTION_CODE (node) == name);
}
+/* A struct for encapsulating location information about an operator
+ and the operation built from it.
+
+ m_operator_loc is the location of the operator
+ m_combined_loc is the location of the compound expression.
+
+ For example, given "a && b" the, operator location is:
+ a && b
+ ^~
+ and the combined location is:
+ a && b
+ ~~^~~~
+ Capturing this information allows for class binary_op_rich_location
+ to provide detailed information about e.g. type mismatches in binary
+ operations where enough location information is available:
+
+ arg_0 op arg_1
+ ~~~~~ ^~ ~~~~~
+ | |
+ | arg1 type
+ arg0 type
+
+ falling back to just showing the combined location:
+
+ arg_0 op arg_1
+ ~~~~~~^~~~~~~~
+
+ where it is not. */
+
+class op_location_t
+{
+public:
+ location_t m_operator_loc;
+ location_t m_combined_loc;
+
+ /* 1-argument ctor, for constructing from a combined location. */
+ op_location_t (location_t combined_loc)
+ : m_operator_loc (UNKNOWN_LOCATION), m_combined_loc (combined_loc)
+ {}
+
+ /* 2-argument ctor, for distinguishing between the operator's location
+ and the combined location. */
+ op_location_t (location_t operator_loc, location_t combined_loc)
+ : m_operator_loc (operator_loc), m_combined_loc (combined_loc)
+ {}
+
+ /* Implicitly convert back to a location_t, using the combined location. */
+ operator location_t () const { return m_combined_loc; }
+};
+
#endif /* GCC_TREE_H */