extern const char tree_code_type[];
#define TREE_CODE_CLASS(CODE) tree_code_type[(int) (CODE)]
+/* Returns nonzero iff CLASS is not the tree code of a type. */
+
+#define IS_NON_TYPE_CODE_CLASS(CLASS) (strchr ("xbcdr<12se", (CLASS)) != 0)
+
/* Returns nonzero iff CLASS is the tree-code class of an
expression. */
unsigned readonly_flag : 1;
unsigned unsigned_flag : 1;
unsigned asm_written_flag: 1;
- unsigned unused_0 : 1;
-
unsigned used_flag : 1;
+
unsigned nothrow_flag : 1;
unsigned static_flag : 1;
unsigned public_flag : 1;
unsigned private_flag : 1;
unsigned protected_flag : 1;
unsigned deprecated_flag : 1;
+
+ unsigned unused_0 : 1;
unsigned unused_1 : 1;
unsigned lang_flag_0 : 1;
TREE_STATIC in
VAR_DECL, FUNCTION_DECL, CONSTRUCTOR, ADDR_EXPR
TREE_NO_UNUSED_WARNING in
- CONVERT_EXPR, NOP_EXPR, COMPOUND_EXPR
+ CONVERT_EXPR, NOP_EXPR, COMPOUND_EXPR, NON_LVALUE_EXPR
+ ??? plus other expressions, apparently (e.g. MODIFY_EXPR).
TREE_VIA_VIRTUAL in
TREE_LIST or TREE_VEC
TREE_CONSTANT_OVERFLOW in
CLEANUP_EH_ONLY in
TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT,
TREE_LIST elements of a block's cleanup list.
+ TYPE_REF_CAN_ALIAS_ALL in
+ POINTER_TYPE, REFERENCE_TYPE
public_flag:
TREE_OVERFLOW in
INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
+ ??? and other expressions?
TREE_PUBLIC in
VAR_DECL or FUNCTION_DECL or IDENTIFIER_NODE
EXPR_WFL_EMIT_LINE_NOTE in
TREE_SIDE_EFFECTS in
all expressions
+ all decls
+ all constants
volatile_flag:
TREE_CONSTANT in
all expressions
+ all decls
+ all constants
unsigned_flag:
- TREE_UNSIGNED in
- INTEGER_TYPE, ENUMERAL_TYPE, FIELD_DECL
+ TYPE_UNSIGNED in
+ all types
+ DECL_UNSIGNED in
+ all decls
+ BIT_FIELD_REF_UNSIGNED in
+ BIT_FIELD_REF
SAVE_EXPR_NOPLACEHOLDER in
SAVE_EXPR
__LINE__, __FUNCTION__); \
__t; })
+#define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) __extension__ \
+({ const tree __t = (T); \
+ if (TREE_CODE (__t) != (CODE1) \
+ && TREE_CODE (__t) != (CODE2) \
+ && TREE_CODE (__t) != (CODE3) \
+ && TREE_CODE (__t) != (CODE4)) \
+ tree_check4_failed (__t, (CODE1), (CODE2), (CODE3), (CODE4), \
+ __FILE__, __LINE__, __FUNCTION__); \
+ __t; })
+
#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) __extension__ \
({ const tree __t = (T); \
if (TREE_CODE (__t) != (CODE1) \
({ const tree __t = (T); \
char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); \
if (!IS_EXPR_CODE_CLASS (__c)) \
- tree_class_check_failed (__t, 'e', __FILE__, __LINE__, \
+ tree_class_check_failed (__t, 'E', __FILE__, __LINE__, \
+ __FUNCTION__); \
+ __t; })
+
+/* These checks have to be special cased. */
+#define NON_TYPE_CHECK(T) __extension__ \
+({ const tree __t = (T); \
+ char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); \
+ if (!IS_NON_TYPE_CODE_CLASS (__c)) \
+ tree_class_check_failed (__t, 'T', __FILE__, __LINE__, \
__FUNCTION__); \
__t; })
enum tree_code, const char *, int,
const char *)
ATTRIBUTE_NORETURN;
+extern void tree_check4_failed (const tree, enum tree_code, enum tree_code,
+ enum tree_code, enum tree_code,
+ const char *, int, const char *)
+ ATTRIBUTE_NORETURN;
extern void tree_check5_failed (const tree, enum tree_code, enum tree_code,
enum tree_code, enum tree_code, enum tree_code,
const char *, int, const char *)
#define TREE_CHECK(T, CODE) (T)
#define TREE_CHECK2(T, CODE1, CODE2) (T)
#define TREE_CHECK3(T, CODE1, CODE2, CODE3) (T)
+#define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) (T)
#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) (T)
#define TREE_CLASS_CHECK(T, CODE) (T)
#define EXPR_CHECK(T) (T)
+#define NON_TYPE_CHECK(T) (T)
#define TREE_VEC_ELT_CHECK(T, I) ((T)->vec.a[I])
#define TREE_OPERAND_CHECK(T, I) ((T)->exp.operands[I])
#define TREE_OPERAND_CHECK_CODE(T, CODE, I) ((T)->exp.operands[I])
#define CST_CHECK(T) TREE_CLASS_CHECK (T, 'c')
#define STMT_CHECK(T) TREE_CLASS_CHECK (T, 's')
#define FUNC_OR_METHOD_CHECK(T) TREE_CHECK2 (T, FUNCTION_TYPE, METHOD_TYPE)
+#define PTR_OR_REF_CHECK(T) TREE_CHECK2 (T, POINTER_TYPE, REFERENCE_TYPE)
#define SET_ARRAY_OR_VECTOR_CHECK(T) \
TREE_CHECK3 (T, ARRAY_TYPE, SET_TYPE, VECTOR_TYPE)
&& TREE_OPERAND (EXP, 0) != error_mark_node \
&& (TYPE_MODE (TREE_TYPE (EXP)) \
== TYPE_MODE (TREE_TYPE (TREE_OPERAND (EXP, 0)))) \
- && (TREE_UNSIGNED (TREE_TYPE (EXP)) \
- == TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
+ && (TYPE_UNSIGNED (TREE_TYPE (EXP)) \
+ == TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
(EXP) = TREE_OPERAND (EXP, 0)
/* Like STRIP_NOPS, but don't alter the TREE_TYPE main variant either. */
/* In a VAR_DECL, nonzero means allocate static storage.
In a FUNCTION_DECL, nonzero if function has been defined.
- In a CONSTRUCTOR, nonzero means allocate static storage. */
+ In a CONSTRUCTOR, nonzero means allocate static storage.
+
+ ??? This is also used in lots of other nodes in unclear ways which
+ should be cleaned up some day. */
#define TREE_STATIC(NODE) ((NODE)->common.static_flag)
/* In a TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT, or element of a
executed if an exception is thrown, not on normal exit of its scope. */
#define CLEANUP_EH_ONLY(NODE) ((NODE)->common.static_flag)
-/* In a CONVERT_EXPR, NOP_EXPR or COMPOUND_EXPR, this means the node was
- made implicitly and should not lead to an "unused value" warning. */
-#define TREE_NO_UNUSED_WARNING(NODE) ((NODE)->common.static_flag)
+/* In a CONVERT_EXPR, NOP_EXPR, NON_LVALUE_EXPR or COMPOUND_EXPR, this means
+ the node was made implicitly and should not lead to an "unused value"
+ warning.
+
+ ??? Apparently this is also used on other expression types (such as
+ MODIFY_EXPR. This needs to be cleaned up sometime. */
+#define TREE_NO_UNUSED_WARNING(NODE) (EXPR_CHECK (NODE)->common.static_flag)
/* Nonzero for a TREE_LIST or TREE_VEC node means that the derivation
chain is via a `virtual' declaration. */
-#define TREE_VIA_VIRTUAL(NODE) ((NODE)->common.static_flag)
+#define TREE_VIA_VIRTUAL(NODE) \
+ (TREE_CHECK2 (NODE, TREE_LIST, TREE_VEC)->common.static_flag)
/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST this means
there was an overflow in folding. This is distinct from
TREE_OVERFLOW because ANSI C requires a diagnostic when overflows
occur in constant expressions. */
-#define TREE_CONSTANT_OVERFLOW(NODE) ((NODE)->common.static_flag)
+#define TREE_CONSTANT_OVERFLOW(NODE) (CST_CHECK (NODE)->common.static_flag)
/* In an IDENTIFIER_NODE, this means that assemble_name was called with
this string as an argument. */
#define TREE_SYMBOL_REFERENCED(NODE) \
(IDENTIFIER_NODE_CHECK (NODE)->common.static_flag)
+/* Nonzero in a pointer or reference type means the data pointed to
+ by this type can alias anything. */
+#define TYPE_REF_CAN_ALIAS_ALL(NODE) \
+ (PTR_OR_REF_CHECK (NODE)->common.static_flag)
+
/* In an INTEGER_CST, REAL_CST, COMPLEX_CST, or VECTOR_CST, this means
there was an overflow in folding, and no warning has been issued
- for this subexpression. TREE_OVERFLOW implies
- TREE_CONSTANT_OVERFLOW, but not vice versa. */
+ for this subexpression. TREE_OVERFLOW implies TREE_CONSTANT_OVERFLOW,
+ but not vice versa.
+
+ ??? Apparently, lots of code assumes this is defined in all
+ expressions. */
#define TREE_OVERFLOW(NODE) ((NODE)->common.public_flag)
/* In a VAR_DECL or FUNCTION_DECL,
for this name in an inner scope. */
#define TREE_PUBLIC(NODE) ((NODE)->common.public_flag)
-/* In any expression, nonzero means it has side effects or reevaluation
- of the whole expression could produce a different value.
- This is set if any subexpression is a function call, a side effect
- or a reference to a volatile variable.
- In a ..._DECL, this is set only if the declaration said `volatile'. */
-#define TREE_SIDE_EFFECTS(NODE) ((NODE)->common.side_effects_flag)
+/* In any expression, decl, or constant, nonzero means it has side effects or
+ reevaluation of the whole expression could produce a different value.
+ This is set if any subexpression is a function call, a side effect or a
+ reference to a volatile variable. In a ..._DECL, this is set only if the
+ declaration said `volatile'. This will never be set for a constant. */
+#define TREE_SIDE_EFFECTS(NODE) \
+ (NON_TYPE_CHECK (NODE)->common.side_effects_flag)
/* Nonzero means this expression is volatile in the C sense:
its address should be of type `volatile WHATEVER *'.
#define TREE_THIS_VOLATILE(NODE) ((NODE)->common.volatile_flag)
/* In a VAR_DECL, PARM_DECL or FIELD_DECL, or any kind of ..._REF node,
- nonzero means it may not be the lhs of an assignment.
- In a ..._TYPE node, means this type is const-qualified
- (but the macro TYPE_READONLY should be used instead of this macro
- when the node is a type). */
-#define TREE_READONLY(NODE) ((NODE)->common.readonly_flag)
+ nonzero means it may not be the lhs of an assignment. */
+#define TREE_READONLY(NODE) (NON_TYPE_CHECK (NODE)->common.readonly_flag)
/* Nonzero if NODE is a _DECL with TREE_READONLY set. */
-#define TREE_READONLY_DECL_P(NODE) (TREE_READONLY (NODE) && DECL_P (NODE))
+#define TREE_READONLY_DECL_P(NODE) (DECL_P (NODE) && TREE_READONLY (NODE))
-/* Value of expression is constant.
- Always appears in all ..._CST nodes.
- May also appear in an arithmetic expression, an ADDR_EXPR or a CONSTRUCTOR
- if the value is constant. */
-#define TREE_CONSTANT(NODE) ((NODE)->common.constant_flag)
+/* Value of expression is constant. Always on in all ..._CST nodes. May
+ also appear in an expression or decl where the value is constant. */
+#define TREE_CONSTANT(NODE) (NON_TYPE_CHECK (NODE)->common.constant_flag)
-/* In INTEGER_TYPE or ENUMERAL_TYPE nodes, means an unsigned type.
- In FIELD_DECL nodes, means an unsigned bit field. */
-#define TREE_UNSIGNED(NODE) ((NODE)->common.unsigned_flag)
+/* In a decl (most significantly a FIELD_DECL), means an unsigned field. */
+#define DECL_UNSIGNED(NODE) (DECL_CHECK (NODE)->common.unsigned_flag)
+
+/* In a BIT_FIELD_REF, means the bitfield is to be interpreted as unsigned. */
+#define BIT_FIELD_REF_UNSIGNED(NODE) \
+ (BIT_FIELD_REF_CHECK (NODE)->common.unsigned_flag)
+
+/* In integral and pointer types, means an unsigned type. */
+#define TYPE_UNSIGNED(NODE) (TYPE_CHECK (NODE)->common.unsigned_flag)
#define TYPE_TRAP_SIGNED(NODE) \
- (flag_trapv && ! TREE_UNSIGNED (TYPE_CHECK (NODE)))
+ (flag_trapv && ! TYPE_UNSIGNED (NODE))
/* Nonzero in a VAR_DECL means assembler code has been written.
Nonzero in a FUNCTION_DECL means that the function has been compiled.
#define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND_CHECK_CODE (NODE, SAVE_EXPR, 1)
#define SAVE_EXPR_RTL(NODE) TREE_RTL_OPERAND_CHECK (NODE, SAVE_EXPR, 2)
-#define SAVE_EXPR_NOPLACEHOLDER(NODE) TREE_UNSIGNED (SAVE_EXPR_CHECK (NODE))
+#define SAVE_EXPR_NOPLACEHOLDER(NODE) \
+ (SAVE_EXPR_CHECK (NODE)->common.unsigned_flag)
+
/* Nonzero if the SAVE_EXPRs value should be kept, even if it occurs
both in normal code and in a handler. (Normally, in a handler, all
SAVE_EXPRs are unsaved, meaning that their values are
#define TYPE_OFFSET_BASETYPE(NODE) (OFFSET_TYPE_CHECK (NODE)->type.maxval)
#define TYPE_POINTER_TO(NODE) (TYPE_CHECK (NODE)->type.pointer_to)
#define TYPE_REFERENCE_TO(NODE) (TYPE_CHECK (NODE)->type.reference_to)
+#define TYPE_NEXT_PTR_TO(NODE) (POINTER_TYPE_CHECK (NODE)->type.minval)
+#define TYPE_NEXT_REF_TO(NODE) (REFERENCE_TYPE_CHECK (NODE)->type.minval)
#define TYPE_MIN_VALUE(NODE) (NUMERICAL_TYPE_CHECK (NODE)->type.minval)
#define TYPE_MAX_VALUE(NODE) (NUMERICAL_TYPE_CHECK (NODE)->type.maxval)
#define TYPE_PRECISION(NODE) (TYPE_CHECK (NODE)->type.precision)
For a VAR_DECL, holds the initial value.
For a PARM_DECL, not used--default
values for parameters are encoded in the type of the function,
- not in the PARM_DECL slot. */
+ not in the PARM_DECL slot.
+
+ ??? Need to figure out some way to check this isn't a PARM_DECL. */
#define DECL_INITIAL(NODE) (DECL_CHECK (NODE)->decl.initial)
/* For a PARM_DECL, records the data type used to pass the argument,
which may be different from the type seen in the program. */
unsigned int align : 24;
unsigned int off_align : 8;
} a;
- } GTY ((skip (""))) u1;
+ } GTY ((skip)) u1;
tree size_unit;
tree name;
extern void initialize_sizetypes (void);
extern void set_sizetype (tree);
extern void fixup_unsigned_type (tree);
-extern tree build_pointer_type_for_mode (tree, enum machine_mode);
+extern tree build_pointer_type_for_mode (tree, enum machine_mode, bool);
extern tree build_pointer_type (tree);
-extern tree build_reference_type_for_mode (tree, enum machine_mode);
+extern tree build_reference_type_for_mode (tree, enum 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 (tree innertype, int nunits);
extern tree substitute_in_expr (tree, tree, tree);
+/* This macro calls the above function but short-circuits the common
+ case of a constant to save time and also checks for NULL. */
+
+#define SUBSTITUTE_IN_EXPR(EXP, F, R) \
+ ((EXP) == 0 || TREE_CONSTANT (EXP) ? (EXP) : substitute_in_expr (EXP, F, R))
+
+/* Similar, but look for a PLACEHOLDER_EXPR in EXP and find a replacement
+ for it within OBJ, a tree that is an object or a chain of references. */
+
+extern tree substitute_placeholder_in_expr (tree, tree);
+
+/* This macro calls the above function but short-circuits the common
+ case of a constant to save time and also checks for NULL. */
+
+#define SUBSTITUTE_PLACEHOLDER_IN_EXPR(EXP, OBJ) \
+ ((EXP) == 0 || TREE_CONSTANT (EXP) ? (EXP) \
+ : substitute_placeholder_in_expr (EXP, OBJ))
+
/* variable_size (EXP) is like save_expr (EXP) except that it
is for the special case of something that is part of a
variable size for a data type. It makes special arrangements
extern tree variable_size (tree);
+/* Given a type T, force elaboration of any SAVE_EXPRs used in the definition
+ of that type. */
+
+extern void force_type_save_exprs (tree);
+
/* stabilize_reference (EXP) returns a reference equivalent to EXP
but it can be used multiple times
and only evaluate the subexpressions once. */
extern tree fold (tree);
extern tree fold_initializer (tree);
+extern tree fold_convert (tree, tree);
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
extern int force_fit_type (tree, int);