/* Definitions for the ubiquitous 'tree' type for GNU compilers.
- Copyright (C) 1989-2014 Free Software Foundation, Inc.
+ Copyright (C) 1989-2015 Free Software Foundation, Inc.
This file is part of GCC.
#define GCC_TREE_H
#include "tree-core.h"
-#include "wide-int.h"
-
-/* These includes are required here because they provide declarations
- used by inline functions in this file.
-
- FIXME - Move these users elsewhere? */
-#include "fold-const.h"
/* Macros for initializing `tree_contains_struct'. */
#define MARK_TS_BASE(C) \
#define NON_TYPE_CHECK(T) \
(non_type_check ((T), __FILE__, __LINE__, __FUNCTION__))
+/* These checks have to be special cased. */
+#define ANY_INTEGRAL_TYPE_CHECK(T) \
+(any_integral_type_check ((T), __FILE__, __LINE__, __FUNCTION__))
+
#define TREE_INT_CST_ELT_CHECK(T, I) \
(*tree_int_cst_elt_check ((T), (I), __FILE__, __LINE__, __FUNCTION__))
#define OMP_CLAUSE_ELT_CHECK(T, i) ((T)->omp_clause.ops[i])
#define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) (T)
#define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) (T)
+#define ANY_INTEGRAL_TYPE_CHECK(T) (T)
#define TREE_CHAIN(NODE) ((NODE)->common.chain)
#define TREE_TYPE(NODE) ((NODE)->typed.type)
#define CONVERT_EXPR_CODE_P(CODE) \
((CODE) == NOP_EXPR || (CODE) == CONVERT_EXPR)
-/* Similarly, but accept an expressions instead of a tree code. */
+/* Similarly, but accept an expression instead of a tree code. */
#define CONVERT_EXPR_P(EXP) CONVERT_EXPR_CODE_P (TREE_CODE (EXP))
/* Generate case for NOP_EXPR, CONVERT_EXPR. */
|| TREE_CODE (TYPE) == BOOLEAN_TYPE \
|| TREE_CODE (TYPE) == INTEGER_TYPE)
+/* Nonzero if TYPE represents an integral type, including complex
+ and vector integer types. */
+
+#define ANY_INTEGRAL_TYPE_P(TYPE) \
+ (INTEGRAL_TYPE_P (TYPE) \
+ || ((TREE_CODE (TYPE) == COMPLEX_TYPE \
+ || VECTOR_TYPE_P (TYPE)) \
+ && INTEGRAL_TYPE_P (TREE_TYPE (TYPE))))
+
/* Nonzero if TYPE represents a non-saturating fixed-point type. */
#define NON_SAT_FIXED_POINT_TYPE_P(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)
/* True if overflow wraps around for the given integral type. That
is, TYPE_MAX + 1 == TYPE_MIN. */
#define TYPE_OVERFLOW_WRAPS(TYPE) \
- (TYPE_UNSIGNED (TYPE) || flag_wrapv)
+ (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.
it will be appropriate to issue the warning immediately, and in
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) \
- (!TYPE_UNSIGNED (TYPE) && !flag_wrapv && !flag_trapv && flag_strict_overflow)
+#define TYPE_OVERFLOW_UNDEFINED(TYPE) \
+ (!ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag \
+ && !flag_wrapv && !flag_trapv && flag_strict_overflow)
/* True if overflow for the given integral type should issue a
trap. */
#define TYPE_OVERFLOW_TRAPS(TYPE) \
- (!TYPE_UNSIGNED (TYPE) && flag_trapv)
+ (!ANY_INTEGRAL_TYPE_CHECK(TYPE)->base.u.bits.unsigned_flag && flag_trapv)
+
+/* True if an overflow is to be preserved for sanitization. */
+#define TYPE_OVERFLOW_SANITIZED(TYPE) \
+ (INTEGRAL_TYPE_P (TYPE) \
+ && !TYPE_OVERFLOW_WRAPS (TYPE) \
+ && (flag_sanitize & SANITIZE_SI_OVERFLOW))
/* True if pointer types have undefined overflow. */
#define POINTER_TYPE_OVERFLOW_UNDEFINED (flag_strict_overflow)
#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)
+
/* In a type, nonzero means that all objects of the type are guaranteed by the
language or front-end to be properly aligned, so we can indicate that a MEM
of this type is aligned at least to the alignment of the type, even if it
#define TMR_STEP(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 3))
#define TMR_INDEX2(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 4))
+#define MR_DEPENDENCE_CLIQUE(NODE) \
+ (TREE_CHECK2 (NODE, MEM_REF, TARGET_MEM_REF)->base.u.dependence_info.clique)
+#define MR_DEPENDENCE_BASE(NODE) \
+ (TREE_CHECK2 (NODE, MEM_REF, TARGET_MEM_REF)->base.u.dependence_info.base)
+
/* The operands of a BIND_EXPR. */
#define BIND_EXPR_VARS(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 0))
#define BIND_EXPR_BODY(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 1))
#define TRANSACTION_EXPR_RELAXED(NODE) \
(TRANSACTION_EXPR_CHECK (NODE)->base.public_flag)
-/* OpenMP directive and clause accessors. */
+/* OpenMP and OpenACC directive and clause accessors. */
+/* 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, OMP_PARALLEL, OMP_CRITICAL), 0)
+ TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_CRITICAL), 0)
#define OMP_CLAUSES(NODE) \
- TREE_OPERAND (TREE_RANGE_CHECK (NODE, OMP_PARALLEL, OMP_SINGLE), 1)
+ TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_PARALLEL, OMP_SINGLE), 1)
+
+/* Generic accessors for OMP nodes that keep clauses as operand 0. */
+#define OMP_STANDALONE_CLAUSES(NODE) \
+ TREE_OPERAND (TREE_RANGE_CHECK (NODE, OACC_CACHE, OMP_TARGET_UPDATE), 0)
+
+#define OACC_PARALLEL_BODY(NODE) \
+ TREE_OPERAND (OACC_PARALLEL_CHECK (NODE), 0)
+#define OACC_PARALLEL_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_PARALLEL_CHECK (NODE), 1)
+
+#define OACC_KERNELS_BODY(NODE) \
+ TREE_OPERAND (OACC_KERNELS_CHECK(NODE), 0)
+#define OACC_KERNELS_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_KERNELS_CHECK(NODE), 1)
+
+#define OACC_DATA_BODY(NODE) \
+ TREE_OPERAND (OACC_DATA_CHECK (NODE), 0)
+#define OACC_DATA_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_DATA_CHECK (NODE), 1)
+
+#define OACC_HOST_DATA_BODY(NODE) \
+ TREE_OPERAND (OACC_HOST_DATA_CHECK (NODE), 0)
+#define OACC_HOST_DATA_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_HOST_DATA_CHECK (NODE), 1)
+
+#define OACC_CACHE_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_CACHE_CHECK (NODE), 0)
+
+#define OACC_DECLARE_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_DECLARE_CHECK (NODE), 0)
+
+#define OACC_ENTER_DATA_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_ENTER_DATA_CHECK (NODE), 0)
+
+#define OACC_EXIT_DATA_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_EXIT_DATA_CHECK (NODE), 0)
+
+#define OACC_UPDATE_CLAUSES(NODE) \
+ TREE_OPERAND (OACC_UPDATE_CHECK (NODE), 0)
#define OMP_PARALLEL_BODY(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 0)
#define OMP_PARALLEL_CLAUSES(NODE) TREE_OPERAND (OMP_PARALLEL_CHECK (NODE), 1)
#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, OMP_DISTRIBUTE)
+#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_CLAUSE_SIZE(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
OMP_CLAUSE_FROM, \
- OMP_CLAUSE_MAP), 1)
+ OMP_CLAUSE__CACHE_), 1)
#define OMP_CLAUSE_CHAIN(NODE) TREE_CHAIN (OMP_CLAUSE_CHECK (NODE))
#define OMP_CLAUSE_DECL(NODE) \
#define OMP_SECTION_LAST(NODE) \
(OMP_SECTION_CHECK (NODE)->base.private_flag)
+/* True on an OACC_KERNELS statement if is represents combined kernels loop
+ directive. */
+#define OACC_KERNELS_COMBINED(NODE) \
+ (OACC_KERNELS_CHECK (NODE)->base.private_flag)
+
+/* Like OACC_KERNELS_COMBINED, but for parallel loop directive. */
+#define OACC_PARALLEL_COMBINED(NODE) \
+ (OACC_PARALLEL_CHECK (NODE)->base.private_flag)
+
/* True on an OMP_PARALLEL statement if it represents an explicit
combined parallel work-sharing constructs. */
#define OMP_PARALLEL_COMBINED(NODE) \
(OMP_PARALLEL_CHECK (NODE)->base.private_flag)
+/* True on an OMP_TEAMS statement if it represents an explicit
+ combined teams distribute constructs. */
+#define OMP_TEAMS_COMBINED(NODE) \
+ (OMP_TEAMS_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) \
#define OMP_CLAUSE_SCHEDULE_CHUNK_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SCHEDULE), 0)
+/* OpenACC clause expressions */
+#define OMP_CLAUSE_GANG_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_GANG), 0)
+#define OMP_CLAUSE_GANG_STATIC_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_GANG), 1)
+#define OMP_CLAUSE_ASYNC_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ASYNC), 0)
+#define OMP_CLAUSE_WAIT_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_WAIT), 0)
+#define OMP_CLAUSE_VECTOR_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_VECTOR), 0)
+#define OMP_CLAUSE_WORKER_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_WORKER), 0)
+#define OMP_CLAUSE_NUM_GANGS_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_GANGS), 0)
+#define OMP_CLAUSE_NUM_WORKERS_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_NUM_WORKERS), 0)
+#define OMP_CLAUSE_VECTOR_LENGTH_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND ( \
+ OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_VECTOR_LENGTH), 0)
+
#define OMP_CLAUSE_DEPEND_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEPEND)->omp_clause.subcode.depend_kind)
#define OMP_CLAUSE_MAP_KIND(NODE) \
- (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)->omp_clause.subcode.map_kind)
+ ((enum gomp_map_kind) OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)->omp_clause.subcode.map_kind)
+#define OMP_CLAUSE_SET_MAP_KIND(NODE, MAP_KIND) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)->omp_clause.subcode.map_kind \
+ = (unsigned char) (MAP_KIND))
/* Nonzero if this map clause is for array (rather than pointer) based array
- section with zero bias. Both the non-decl OMP_CLAUSE_MAP and
- correspoidng OMP_CLAUSE_MAP_POINTER clause are marked with this flag. */
+ section with zero bias. Both the non-decl OMP_CLAUSE_MAP and corresponding
+ OMP_CLAUSE_MAP with GOMP_MAP_POINTER are marked with this flag. */
#define OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_MAP)->base.public_flag)
#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_DIE(NODE) (BLOCK_CHECK (NODE)->block.die)
/* True if BLOCK has the same ranges as its BLOCK_SUPERCONTEXT. */
#define BLOCK_SAME_RANGE(NODE) (BLOCK_CHECK (NODE)->base.u.bits.nameless_flag)
#define SET_TYPE_MODE(NODE, MODE) \
(TYPE_CHECK (NODE)->type_common.mode = (MODE))
+extern machine_mode element_mode (const_tree t);
+
/* 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
equal (based on the semantics of the language), then they will have
information, we mustn't try to generate any address information for nodes
marked as "abstract instances" because we don't actually generate
any code or allocate any data space for such instances. */
-#define DECL_ABSTRACT(NODE) \
+#define DECL_ABSTRACT_P(NODE) \
(DECL_COMMON_CHECK (NODE)->decl_common.abstract_flag)
/* Language-specific decl information. */
/* The name of the object as the assembler will see it (but before any
translations made by ASM_OUTPUT_LABELREF). Often this is the same
- as DECL_NAME. It is an IDENTIFIER_NODE. */
+ as DECL_NAME. It is an IDENTIFIER_NODE.
+
+ ASSEMBLER_NAME of TYPE_DECLS may store global name of type used for
+ One Definition Rule based type merging at LTO. It is computed only for
+ LTO compilation and C++. */
#define DECL_ASSEMBLER_NAME(NODE) decl_assembler_name (NODE)
/* Return true if NODE is a NODE that can contain a DECL_ASSEMBLER_NAME.
/* In a FUNCTION_DECL indicates that a static chain is needed. */
#define DECL_STATIC_CHAIN(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->function_decl.regdecl_flag)
+ (FUNCTION_DECL_CHECK (NODE)->decl_with_vis.regdecl_flag)
/* Nonzero for a decl that cgraph has decided should be inlined into
at least one call site. It is not meaningful to look at this
#define DECL_BUILT_IN_CLASS(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
-/* In FUNCTION_DECL, a chain of ..._DECL nodes.
- VAR_DECL and PARM_DECL reserve the arguments slot for language-specific
- uses. */
+/* In FUNCTION_DECL, a chain of ..._DECL nodes. */
#define DECL_ARGUMENTS(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->decl_non_common.arguments)
-#define DECL_ARGUMENT_FLD(NODE) \
- (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.arguments)
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.arguments)
/* In FUNCTION_DECL, the function specific target options to use when compiling
this function. */
(STATEMENT_LIST_CHECK (NODE)->stmt_list.tail)
#define TREE_OPTIMIZATION(NODE) \
- (&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
+ (OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
#define TREE_OPTIMIZATION_OPTABS(NODE) \
(OPTIMIZATION_NODE_CHECK (NODE)->optimization.optabs)
extern tree build_optimization_node (struct gcc_options *opts);
#define TREE_TARGET_OPTION(NODE) \
- (&TARGET_OPTION_NODE_CHECK (NODE)->target_option.opts)
+ (TARGET_OPTION_NODE_CHECK (NODE)->target_option.opts)
#define TREE_TARGET_GLOBALS(NODE) \
(TARGET_OPTION_NODE_CHECK (NODE)->target_option.globals)
return &CONST_CAST_TREE (__t)->int_cst.val[__i];
}
+/* Workaround -Wstrict-overflow false positive during profiledbootstrap. */
+
+# if GCC_VERSION >= 4006
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+#endif
+
inline tree *
tree_vec_elt_check (tree __t, int __i,
const char *__f, int __l, const char *__g)
return &CONST_CAST_TREE (__t)->vec.a[__i];
}
+# if GCC_VERSION >= 4006
+#pragma GCC diagnostic pop
+#endif
+
inline tree *
omp_clause_elt_check (tree __t, int __i,
const char *__f, int __l, const char *__g)
return &__t->omp_clause.ops[__i];
}
+/* These checks have to be special cased. */
+
+inline tree
+any_integral_type_check (tree __t, const char *__f, int __l, const char *__g)
+{
+ if (!ANY_INTEGRAL_TYPE_P (__t))
+ tree_check_failed (__t, __f, __l, __g, BOOLEAN_TYPE, ENUMERAL_TYPE,
+ INTEGER_TYPE, 0);
+ return __t;
+}
+
inline const_tree
tree_check (const_tree __t, const char *__f, int __l, const char *__g,
tree_code __c)
return __t;
}
+# if GCC_VERSION >= 4006
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-overflow"
+#endif
+
inline const_tree *
tree_vec_elt_check (const_tree __t, int __i,
const char *__f, int __l, const char *__g)
//return &__t->vec.a[__i];
}
+# if GCC_VERSION >= 4006
+#pragma GCC diagnostic pop
+#endif
+
inline const_tree *
omp_clause_elt_check (const_tree __t, int __i,
const char *__f, int __l, const char *__g)
return CONST_CAST (const_tree *, &__t->omp_clause.ops[__i]);
}
+inline const_tree
+any_integral_type_check (const_tree __t, const char *__f, int __l,
+ const char *__g)
+{
+ if (!ANY_INTEGRAL_TYPE_P (__t))
+ tree_check_failed (__t, __f, __l, __g, BOOLEAN_TYPE, ENUMERAL_TYPE,
+ INTEGER_TYPE, 0);
+ return __t;
+}
+
#endif
/* Compute the number of operands in an expression node NODE. For
#define complex_double_type_node global_trees[TI_COMPLEX_DOUBLE_TYPE]
#define complex_long_double_type_node global_trees[TI_COMPLEX_LONG_DOUBLE_TYPE]
+#define 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 long_unsigned_type_node integer_types[itk_unsigned_long]
#define long_long_integer_type_node integer_types[itk_long_long]
#define long_long_unsigned_type_node integer_types[itk_unsigned_long_long]
-#define int128_integer_type_node integer_types[itk_int128]
-#define int128_unsigned_type_node integer_types[itk_unsigned_int128]
/* True if NODE is an erroneous expression. */
extern tree signed_type_for (tree);
extern tree unsigned_type_for (tree);
extern tree truth_type_for (tree);
-extern tree build_pointer_type_for_mode (tree, enum machine_mode, bool);
+extern tree build_pointer_type_for_mode (tree, machine_mode, bool);
extern tree build_pointer_type (tree);
-extern tree build_reference_type_for_mode (tree, enum machine_mode, bool);
+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, enum machine_mode);
+extern tree build_vector_type_for_mode (tree, machine_mode);
extern tree build_vector_type (tree innertype, int nunits);
extern tree build_opaque_vector_type (tree innertype, int nunits);
extern tree build_index_type (tree);
extern tree build_decl_attribute_variant (tree, tree);
extern tree build_type_attribute_qual_variant (tree, tree, int);
+extern bool attribute_value_equal (const_tree, const_tree);
+
/* Return 0 if the attributes for two types are incompatible, 1 if they
are compatible, and 2 if they are nearly compatible (which causes a
warning to be generated). */
extern tree merge_attributes (tree, tree);
-#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
/* Given two Windows decl attributes lists, possibly including
dllimport, return a list of their union . */
extern tree merge_dllimport_decl_attributes (tree, tree);
/* Handle a "dllimport" or "dllexport" attribute. */
extern tree handle_dll_attribute (tree *, tree, tree, int, bool *);
-#endif
+
+/* Returns true iff unqualified CAND and BASE are equivalent. */
+
+extern bool check_base_type (const_tree cand, const_tree base);
/* Check whether CAND is suitable to be returned from get_qualified_type
(BASE, TYPE_QUALS). */
extern HOST_WIDE_INT int_size_in_bytes (const_tree);
extern HOST_WIDE_INT max_int_size_in_bytes (const_tree);
extern tree bit_position (const_tree);
-extern HOST_WIDE_INT int_bit_position (const_tree);
extern tree byte_position (const_tree);
extern HOST_WIDE_INT int_byte_position (const_tree);
extern int 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);
+
/* integer_all_onesp (tree x) is nonzero if X is an integer constant
all of whose significant bits are 1. */
extern int 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 cst_and_fits_in_hwi (const_tree);
extern tree num_ending_zeros (const_tree);
extern tree create_artificial_label (location_t);
extern const char *get_name (tree);
extern bool stdarg_p (const_tree);
-extern bool prototype_p (tree);
-extern bool is_typedef_decl (tree x);
-extern bool typedef_variant_p (tree);
+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_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 tree tree_strip_nop_conversions (tree);
extern tree tree_strip_sign_nop_conversions (tree);
extern const_tree strip_invariant_refs (const_tree);
extern void warn_deprecated_use (tree, tree);
extern void cache_integer_cst (tree);
+/* Return the memory model from a host integer. */
+static inline enum memmodel
+memmodel_from_int (unsigned HOST_WIDE_INT val)
+{
+ return (enum memmodel) (val & MEMMODEL_MASK);
+}
+
+/* Return the base memory model from a host integer. */
+static inline enum memmodel
+memmodel_base (unsigned HOST_WIDE_INT val)
+{
+ return (enum memmodel) (val & MEMMODEL_BASE_MASK);
+}
+
+/* Return TRUE if the memory model is RELAXED. */
+static inline bool
+is_mm_relaxed (enum memmodel model)
+{
+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELAXED;
+}
+
+/* Return TRUE if the memory model is CONSUME. */
+static inline bool
+is_mm_consume (enum memmodel model)
+{
+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_CONSUME;
+}
+
+/* Return TRUE if the memory model is ACQUIRE. */
+static inline bool
+is_mm_acquire (enum memmodel model)
+{
+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQUIRE;
+}
+
+/* Return TRUE if the memory model is RELEASE. */
+static inline bool
+is_mm_release (enum memmodel model)
+{
+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_RELEASE;
+}
+
+/* Return TRUE if the memory model is ACQ_REL. */
+static inline bool
+is_mm_acq_rel (enum memmodel model)
+{
+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_ACQ_REL;
+}
+
+/* Return TRUE if the memory model is SEQ_CST. */
+static inline bool
+is_mm_seq_cst (enum memmodel model)
+{
+ return (model & MEMMODEL_BASE_MASK) == MEMMODEL_SEQ_CST;
+}
+
+/* Return TRUE if the memory model is a SYNC variant. */
+static inline bool
+is_mm_sync (enum memmodel model)
+{
+ return (model & MEMMODEL_SYNC);
+}
+
/* Compare and hash for any structure which begins with a canonical
pointer. Assumes all pointers are interchangeable, which is sort
of already assumed by gcc elsewhere IIRC. */
&& TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype));
}
-/* Return OFF converted to a pointer offset type suitable as offset for
- POINTER_PLUS_EXPR. Use location LOC for this conversion. */
-static inline tree
-convert_to_ptrofftype_loc (location_t loc, tree off)
-{
- return fold_convert_loc (loc, sizetype, off);
-}
-#define convert_to_ptrofftype(t) convert_to_ptrofftype_loc (UNKNOWN_LOCATION, t)
-
-/* Build and fold a POINTER_PLUS_EXPR at LOC offsetting PTR by OFF. */
-static inline tree
-fold_build_pointer_plus_loc (location_t loc, tree ptr, tree off)
-{
- return fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (ptr),
- ptr, convert_to_ptrofftype_loc (loc, off));
-}
-#define fold_build_pointer_plus(p,o) \
- fold_build_pointer_plus_loc (UNKNOWN_LOCATION, p, o)
-
-/* Build and fold a POINTER_PLUS_EXPR at LOC offsetting PTR by OFF. */
-static inline tree
-fold_build_pointer_plus_hwi_loc (location_t loc, tree ptr, HOST_WIDE_INT off)
-{
- return fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (ptr),
- ptr, size_int (off));
-}
-#define fold_build_pointer_plus_hwi(p,o) \
- fold_build_pointer_plus_hwi_loc (UNKNOWN_LOCATION, p, o)
-
extern tree strip_float_extensions (tree);
extern int really_constant_p (const_tree);
extern bool decl_address_invariant_p (const_tree);
extern int tree_floor_log2 (const_tree);
extern unsigned int tree_ctz (const_tree);
extern int simple_cst_equal (const_tree, const_tree);
-extern hashval_t iterative_hash_expr (const_tree, hashval_t);
-extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
-extern hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);
-extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
+
+namespace inchash
+{
+
+extern void add_expr (const_tree, hash &);
+
+}
+
+/* Compat version until all callers are converted. Return hash for
+ TREE with SEED. */
+static inline hashval_t iterative_hash_expr(const_tree tree, hashval_t seed)
+{
+ inchash::hash hstate (seed);
+ inchash::add_expr (tree, hstate);
+ return hstate.end ();
+}
+
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 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 bool virtual_method_call_p (tree);
-extern tree obj_type_ref_class (tree ref);
-extern bool types_same_for_odr (const_tree type1, const_tree type2);
+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 contains_bitfld_component_ref_p (const_tree);
-extern bool type_in_anonymous_namespace_p (const_tree);
extern bool block_may_fallthru (const_tree);
extern void using_eh_for_cleanups (void);
extern bool using_eh_for_cleanups_p (void);
extern const char *get_tree_code_name (enum tree_code);
extern void set_call_expr_flags (tree, int);
-extern tree walk_tree_1 (tree*, walk_tree_fn, void*, struct pointer_set_t*,
+extern tree walk_tree_1 (tree*, walk_tree_fn, void*, hash_set<tree>*,
walk_tree_lh);
extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*,
walk_tree_lh);
#define walk_tree_without_duplicates(a,b,c) \
walk_tree_without_duplicates_1 (a, b, c, NULL)
-extern tree get_base_address (tree t);
extern tree drop_tree_overflow (tree);
+
+/* Given a memory reference expression T, return its base address.
+ The base address of a memory reference expression is the main
+ object being referenced. */
+extern tree get_base_address (tree t);
+
+/* Return a tree of sizetype representing the size, in bytes, of the element
+ of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+extern tree array_ref_element_size (tree);
+
+/* 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);
+
+/* Return a tree representing the lower bound of the array mentioned in
+ EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
+extern tree array_ref_low_bound (tree);
+
+/* Returns true if REF is an array reference to an array at the end of
+ a structure. If this is the case, the array may be allocated larger
+ than its upper bound implies. */
+extern bool array_at_struct_end_p (tree);
+
+/* Return a tree representing the offset, in bytes, of the field referenced
+ by EXP. This does not include any offset in DECL_FIELD_BIT_OFFSET. */
+extern tree component_ref_field_offset (tree);
+
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 *);
+extern void DEBUG_FUNCTION verify_type (const_tree t);
+extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
+ bool trust_type_canonical = true);
+/* Return simplified tree code of type that is used for canonical type merging. */
+inline enum tree_code
+tree_code_for_canonical_type_merging (enum tree_code code)
+{
+ /* By C standard, each enumerated type shall be compatible with char,
+ a signed integer, or an unsigned integer. The choice of type is
+ implementation defined (in our case it depends on -fshort-enum).
+
+ For this reason we make no distinction between ENUMERAL_TYPE and INTEGER
+ type and compare only by their signedness and precision. */
+ if (code == ENUMERAL_TYPE)
+ return INTEGER_TYPE;
+ /* To allow inter-operability between languages having references and
+ C, we consider reference types and pointers alike. Note that this is
+ not strictly necessary for C-Fortran 2008 interoperability because
+ Fortran define C_PTR type that needs to be compatible with C pointers
+ and we handle this one as ptr_type_node. */
+ if (code == REFERENCE_TYPE)
+ return POINTER_TYPE;
+ return code;
+}
#define tree_map_eq tree_map_base_eq
extern unsigned int tree_map_hash (const void *);
extern unsigned int tree_decl_map_hash (const void *);
#define tree_decl_map_marked_p tree_map_base_marked_p
+struct tree_decl_map_cache_hasher : ggc_cache_ptr_hash<tree_decl_map>
+{
+ static hashval_t hash (tree_decl_map *m) { return tree_decl_map_hash (m); }
+ static bool
+ equal (tree_decl_map *a, tree_decl_map *b)
+ {
+ return tree_decl_map_eq (a, b);
+ }
+
+ static int
+ keep_cache_entry (tree_decl_map *&m)
+ {
+ return ggc_marked_p (m->base.from);
+ }
+};
+
#define tree_int_map_eq tree_map_base_eq
#define tree_int_map_hash tree_map_base_hash
#define tree_int_map_marked_p tree_map_base_marked_p
/* Return true if tree node T is a language-specific node. */
static inline bool
-is_lang_specific (tree t)
+is_lang_specific (const_tree t)
{
return TREE_CODE (t) == LANG_TYPE || TREE_CODE (t) >= NUM_TREE_CODES;
}
{
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- return builtin_info.decl[(size_t)fncode];
+ return builtin_info[(size_t)fncode].decl;
}
/* Return the tree node for an implicit builtin function or NULL. */
size_t uns_fncode = (size_t)fncode;
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- if (!builtin_info.implicit_p[uns_fncode])
+ if (!builtin_info[uns_fncode].implicit_p)
return NULL_TREE;
- return builtin_info.decl[uns_fncode];
+ return builtin_info[uns_fncode].decl;
}
/* Set explicit builtin function nodes and whether it is an implicit
gcc_checking_assert (BUILTIN_VALID_P (fncode)
&& (decl != NULL_TREE || !implicit_p));
- builtin_info.decl[ufncode] = decl;
- builtin_info.implicit_p[ufncode] = implicit_p;
+ builtin_info[ufncode].decl = decl;
+ builtin_info[ufncode].implicit_p = implicit_p;
+ builtin_info[ufncode].declared_p = false;
}
/* Set the implicit flag for a builtin function. */
size_t uns_fncode = (size_t)fncode;
gcc_checking_assert (BUILTIN_VALID_P (fncode)
- && builtin_info.decl[uns_fncode] != NULL_TREE);
+ && builtin_info[uns_fncode].decl != NULL_TREE);
+
+ builtin_info[uns_fncode].implicit_p = implicit_p;
+}
+
+/* Set the declared flag for a builtin function. */
+
+static inline void
+set_builtin_decl_declared_p (enum built_in_function fncode, bool declared_p)
+{
+ size_t uns_fncode = (size_t)fncode;
+
+ gcc_checking_assert (BUILTIN_VALID_P (fncode)
+ && builtin_info[uns_fncode].decl != NULL_TREE);
- builtin_info.implicit_p[uns_fncode] = implicit_p;
+ builtin_info[uns_fncode].declared_p = declared_p;
}
/* Return whether the standard builtin function can be used as an explicit
builtin_decl_explicit_p (enum built_in_function fncode)
{
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- return (builtin_info.decl[(size_t)fncode] != NULL_TREE);
+ return (builtin_info[(size_t)fncode].decl != NULL_TREE);
}
/* Return whether the standard builtin function can be used implicitly. */
size_t uns_fncode = (size_t)fncode;
gcc_checking_assert (BUILTIN_VALID_P (fncode));
- return (builtin_info.decl[uns_fncode] != NULL_TREE
- && builtin_info.implicit_p[uns_fncode]);
+ return (builtin_info[uns_fncode].decl != NULL_TREE
+ && builtin_info[uns_fncode].implicit_p);
+}
+
+/* Return whether the standard builtin function was declared. */
+
+static inline bool
+builtin_decl_declared_p (enum built_in_function fncode)
+{
+ size_t uns_fncode = (size_t)fncode;
+
+ gcc_checking_assert (BUILTIN_VALID_P (fncode));
+ return (builtin_info[uns_fncode].decl != NULL_TREE
+ && builtin_info[uns_fncode].declared_p);
}
/* Return true if T (assumed to be a DECL) is a global variable.
return TREE_OPTIMIZATION (fn_opts);
}
+/* Return pointer to target flags of FNDECL. */
+static inline cl_target_option *
+target_opts_for_fn (const_tree fndecl)
+{
+ tree fn_opts = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+ if (fn_opts == NULL_TREE)
+ fn_opts = target_option_default_node;
+ return fn_opts == NULL_TREE ? NULL : TREE_TARGET_OPTION (fn_opts);
+}
+
/* opt flag for function FNDECL, e.g. opts_for_fn (fndecl, optimize) is
the optimization level of function fndecl. */
#define opt_for_fn(fndecl, opt) (opts_for_fn (fndecl)->x_##opt)
/* 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. */
-#ifndef NO_DOT_IN_LABEL
-#define ANON_AGGRNAME_FORMAT "._%d"
-#define ANON_AGGRNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '.' \
- && IDENTIFIER_POINTER (ID_NODE)[1] == '_')
-#else /* NO_DOT_IN_LABEL */
-#ifndef NO_DOLLAR_IN_LABEL
-#define ANON_AGGRNAME_FORMAT "$_%d"
-#define ANON_AGGRNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '$' \
- && IDENTIFIER_POINTER (ID_NODE)[1] == '_')
-#else /* NO_DOLLAR_IN_LABEL */
-#define ANON_AGGRNAME_PREFIX "__anon_"
-#define ANON_AGGRNAME_P(ID_NODE) \
- (!strncmp (IDENTIFIER_POINTER (ID_NODE), ANON_AGGRNAME_PREFIX, \
- sizeof (ANON_AGGRNAME_PREFIX) - 1))
-#define ANON_AGGRNAME_FORMAT "__anon_%d"
-#endif /* NO_DOLLAR_IN_LABEL */
-#endif /* NO_DOT_IN_LABEL */
+extern const char *anon_aggrname_format();
+extern bool anon_aggrname_p (const_tree);
/* The tree and const_tree overload templates. */
namespace wi
extern void set_decl_rtl (tree, rtx);
extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree);
-/* 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);
-
-extern tree build_personality_function (const char *);
-
/* Given an expression EXP that is a handled_component_p,
look for the ultimate containing object, which is returned and specify
the access position and size. */
extern tree get_inner_reference (tree, HOST_WIDE_INT *, HOST_WIDE_INT *,
- tree *, enum machine_mode *, int *, int *,
+ tree *, machine_mode *, int *, int *,
bool);
-/* Return a tree representing the lower bound of the array mentioned in
- EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */
-extern tree array_ref_low_bound (tree);
+extern tree build_personality_function (const char *);
+
+struct GTY(()) int_n_trees_t {
+ /* These parts are initialized at runtime */
+ tree signed_type;
+ tree unsigned_type;
+};
+
+/* This is also in machmode.h */
+extern bool int_n_enabled_p[NUM_INT_N_ENTS];
+extern GTY(()) struct int_n_trees_t int_n_trees[NUM_INT_N_ENTS];
+
+/* Like bit_position, but return as an integer. It must be representable in
+ that way (since it could be a signed value, we don't have the
+ option of returning -1 like int_size_in_byte can. */
+
+inline HOST_WIDE_INT
+int_bit_position (const_tree field)
+{
+ return (wi::lshift (wi::to_offset (DECL_FIELD_OFFSET (field)), BITS_PER_UNIT_LOG)
+ + wi::to_offset (DECL_FIELD_BIT_OFFSET (field))).to_shwi ();
+}
+
+/* Return true if it makes sense to consider alias set for a type T. */
+
+inline bool
+type_with_alias_set_p (const_tree t)
+{
+ /* Function and method types are never accessed as memory locations. */
+ if (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE)
+ return false;
+
+ if (COMPLETE_TYPE_P (t))
+ return true;
+
+ /* Incomplete types can not 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;
+
+ return false;
+}
+
+extern void gt_ggc_mx (tree &);
+extern void gt_pch_nx (tree &);
+extern void gt_pch_nx (tree &, gt_pointer_operator, void *);
#endif /* GCC_TREE_H */