/* Definitions for the ubiquitous 'tree' type for GNU compilers.
- Copyright (C) 1989-2019 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)\
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, \
/* 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) \
(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 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) \
}
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);
#define OMP_BODY(NODE) \
TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_MASTER), 0)
#define OMP_CLAUSES(NODE) \
- TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_TASKGROUP), 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_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__REDUCTEMP_), 0)
+ OMP_CLAUSE__SCANTEMP_), 0)
#define OMP_CLAUSE_HAS_LOCATION(NODE) \
(LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \
!= UNKNOWN_LOCATION)
#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. */
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_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
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)
+
+/* 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_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)
-
/* 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) \
(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(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->function_decl.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. */
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] = 1 << (precision & 0xff);
+ res.coeffs[0] = HOST_WIDE_INT_1U << (precision & 0xff);
if (precision & 0x100)
- res.coeffs[1] = 1 << (precision & 0xff);
+ res.coeffs[1] = HOST_WIDE_INT_1U << (precision & 0xff);
return res;
}
else
- return (unsigned HOST_WIDE_INT)1 << precision;
+ return HOST_WIDE_INT_1U << precision;
}
/* Set the number of elements in VECTOR_TYPE NODE to SUBPARTS, which must
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
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 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 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 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 *, tree = char_type_node);
+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 (tree);
extern tree build_vector_type_for_mode (tree, machine_mode);
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_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 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. If NONZERO is not
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. */
/* 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
extern bool nonnull_arg_p (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);
/* 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;
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. */
+ 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 DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
}
/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
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 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, int name, built_in_class klass)
+fndecl_built_in_p (const_tree node, unsigned int name, built_in_class klass)
{
- return (fndecl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
+ 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
where it is not. */
-struct op_location_t
+class op_location_t
{
+public:
location_t m_operator_loc;
location_t m_combined_loc;