The gcc source uses several constructs that GDB does not understand. This patch corrects some of them. It affects only compilers built with ENABLE_TREE_CHECKING, and hence release compilers are unaffected.
In particular, I change the implementation of CHECK macros using __extension__ into macros calling inline functions. I do not change the accessor macros themselves. The effect is that it now possible to get useful responses to gdb command like (gdb) print DECL_FUNCTION_CODE (decl) To make the feature work, you must define two macros within gdb. (gdb) macro define __FILE__ "gdb" (gdb) macro define __LINE__ 1 The reason for these definitions is that gdb does not expand the magic preprocessor macros, and then cannot find what it thinks is a regular symbol. (There is now a gdb issue for this problem.) I added these definitions to gdbinit.in. There a non-transparent change in behavior that may affect some users. The inline functions will introduce additional lines in a sequence of gdb 'step' commands. Use 'next' instead. There is one change that appears to be completely transparent, but I mention it here for completeness. The static type of the result of the macros is 'tree' rather than a more specific sub-type of tree. The reason for this change is that gdb does not parse typeof expressions. (There is now a gdb issue for this problem.) Three run average bootstrap times with all default languages enabled are 10234.1 second base and 10272.7 seconds with patch for a 0.377% slow down. Tested on x86-64. Index: gcc/ChangeLog 2011-09-22 Lawrence Crowl <cr...@google.com> * tree.h (tree_check): New. (TREE_CHECK): Use inline function above instead of __extension__. (tree_not_check): New. (TREE_NOT_CHECK): Use inline function above instead of __extension__. (tree_check2): New. (TREE_CHECK2): Use inline function above instead of __extension__. (tree_not_check2): New. (TREE_NOT_CHECK2): Use inline function above instead of __extension__. (tree_check3): New. (TREE_CHECK3): Use inline function above instead of __extension__. (tree_not_check3): New. (TREE_NOT_CHECK3): Use inline function above instead of __extension__. (tree_check4): New. (TREE_CHECK4): Use inline function above instead of __extension__. (tree_not_check4): New. (TREE_NOT_CHECK4): Use inline function above instead of __extension__. (tree_check5): New. (TREE_CHECK5): Use inline function above instead of __extension__. (tree_not_check5): New. (TREE_NOT_CHECK5): Use inline function above instead of __extension__. (contains_struct_check): New. (CONTAINS_STRUCT_CHECK): Use inline function above instead of __extension__. (tree_class_check): New. (TREE_CLASS_CHECK): Use inline function above instead of __extension__. (tree_range_check): New. (TREE_RANGE_CHECK): Use inline function above instead of __extension__. (omp_clause_subcode_check): New. (OMP_CLAUSE_SUBCODE_CHECK): Use inline function above instead of __extension__. (omp_clause_range_check): New. (OMP_CLAUSE_RANGE_CHECK): Use inline function above instead of __extension__. (expr_check): New. (EXPR_CHECK): Use inline function above instead of __extension__. (non_type_check): New. (NON_TYPE_CHECK): Use inline function above instead of __extension__. (tree_vec_elt_check): New. (TREE_VEC_ELT_CHECK): Use inline function above instead of __extension__. (omp_clause_elt_check): New. (OMP_CLAUSE_ELT_CHECK): Use inline function above instead of __extension__. (tree_operand_check): New. (TREE_OPERAND_CHECK): Use inline function above instead of __extension__. (tree_operand_check_code): New. (TREE_OPERAND_CHECK_CODE): Use inline function above instead of __extension__. (TREE_CHAIN): Simplify implementation. (TREE_TYPE): Simplify implementation. (tree_operand_length): Move for compilation dependences. Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 179074) +++ gcc/tree.h (working copy) @@ -737,195 +737,122 @@ enum tree_node_structure_enum { is accessed incorrectly. The macros die with a fatal error. */ #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) -#define TREE_CHECK(T, CODE) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE), 0); \ - __t; }) +#define TREE_CHECK(T, CODE) \ +(tree_check ((T), __FILE__, __LINE__, __FUNCTION__, (CODE))) +/* ((typeof (T)) tree_check ((T), __FILE__, __LINE__, __FUNCTION__, (CODE))) */ -#define TREE_NOT_CHECK(T, CODE) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE), 0); \ - __t; }) +#define TREE_NOT_CHECK(T, CODE) \ +(tree_not_check ((T), __FILE__, __LINE__, __FUNCTION__, (CODE))) +/* ((typeof (T)) tree_not_check ((T), __FILE__, __LINE__, __FUNCTION__, (CODE))) */ -#define TREE_CHECK2(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), 0); \ - __t; }) +#define TREE_CHECK2(T, CODE1, CODE2) \ +(tree_check2 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2))) +/* ((typeof (T)) tree_check2 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2))) */ -#define TREE_NOT_CHECK2(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), 0); \ - __t; }) +#define TREE_NOT_CHECK2(T, CODE1, CODE2) \ +( tree_not_check2 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2))) +/* ((typeof (T)) tree_not_check2 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2))) */ -#define TREE_CHECK3(T, CODE1, CODE2, CODE3) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2) \ - && TREE_CODE (__t) != (CODE3)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), 0); \ - __t; }) +#define TREE_CHECK3(T, CODE1, CODE2, CODE3) \ +(tree_check3 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3))) +/* ((typeof (T)) tree_check3 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3))) */ -#define TREE_NOT_CHECK3(T, CODE1, CODE2, CODE3) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2) \ - || TREE_CODE (__t) == (CODE3)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), 0); \ - __t; }) +#define TREE_NOT_CHECK3(T, CODE1, CODE2, CODE3) \ +(tree_not_check3 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3))) +/* ((typeof (T)) tree_not_check3 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3))) */ -#define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2) \ - && TREE_CODE (__t) != (CODE3) \ - && TREE_CODE (__t) != (CODE4)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), 0); \ - __t; }) +#define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) \ +(tree_check4 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4))) +/* ((typeof (T)) tree_check4 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4))) */ -#define TREE_NOT_CHECK4(T, CODE1, CODE2, CODE3, CODE4) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2) \ - || TREE_CODE (__t) == (CODE3) \ - || TREE_CODE (__t) == (CODE4)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), 0); \ - __t; }) +#define TREE_NOT_CHECK4(T, CODE1, CODE2, CODE3, CODE4) \ +(tree_not_check4 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4))) +/* ((typeof (T)) tree_not_check4 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4))) */ -#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != (CODE1) \ - && TREE_CODE (__t) != (CODE2) \ - && TREE_CODE (__t) != (CODE3) \ - && TREE_CODE (__t) != (CODE4) \ - && TREE_CODE (__t) != (CODE5)) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), (CODE5), 0);\ - __t; }) +#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) \ +(tree_check5 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4), (CODE5))) +/* ((typeof (T)) tree_check5 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4), (CODE5))) */ -#define TREE_NOT_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) == (CODE1) \ - || TREE_CODE (__t) == (CODE2) \ - || TREE_CODE (__t) == (CODE3) \ - || TREE_CODE (__t) == (CODE4) \ - || TREE_CODE (__t) == (CODE5)) \ - tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2), (CODE3), (CODE4), (CODE5), 0);\ - __t; }) +#define TREE_NOT_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) \ +(tree_not_check5 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4), (CODE5))) +/* ((typeof (T)) tree_not_check5 ((T), __FILE__, __LINE__, __FUNCTION__, \ + (CODE1), (CODE2), (CODE3), (CODE4), (CODE5))) */ -#define CONTAINS_STRUCT_CHECK(T, STRUCT) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (tree_contains_struct[TREE_CODE(__t)][(STRUCT)] != 1) \ - tree_contains_struct_check_failed (__t, (STRUCT), __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) +#define CONTAINS_STRUCT_CHECK(T, STRUCT) \ +(contains_struct_check ((T), (STRUCT), \ + __FILE__, __LINE__, __FUNCTION__)) +/* ((typeof (T)) contains_struct_check ((T), (STRUCT), \ + __FILE__, __LINE__, __FUNCTION__)) */ -#define TREE_CLASS_CHECK(T, CLASS) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE_CLASS (TREE_CODE(__t)) != (CLASS)) \ - tree_class_check_failed (__t, (CLASS), __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) +#define TREE_CLASS_CHECK(T, CLASS) \ +(tree_class_check ((T), (CLASS), \ + __FILE__, __LINE__, __FUNCTION__)) +/* ((typeof (T)) tree_class_check ((T), (CLASS), \ + __FILE__, __LINE__, __FUNCTION__)) */ -#define TREE_RANGE_CHECK(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) < (CODE1) || TREE_CODE (__t) > (CODE2)) \ - tree_range_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE1), (CODE2)); \ - __t; }) +#define TREE_RANGE_CHECK(T, CODE1, CODE2) \ +(tree_range_check ((T), (CODE1), (CODE2), \ + __FILE__, __LINE__, __FUNCTION__)) +/* ((typeof (T)) tree_range_check ((T), (CODE1), (CODE2), \ + __FILE__, __LINE__, __FUNCTION__)) */ -#define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != OMP_CLAUSE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - OMP_CLAUSE, 0); \ - if (__t->omp_clause.code != (CODE)) \ - omp_clause_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - (CODE)); \ - __t; }) +#define OMP_CLAUSE_SUBCODE_CHECK(T, CODE) \ +(omp_clause_subcode_check ((T), (CODE), \ + __FILE__, __LINE__, __FUNCTION__)) +/* ((typeof (T)) omp_clause_subcode_check ((T), (CODE), \ + __FILE__, __LINE__, __FUNCTION__)) */ -#define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TREE_CODE (__t) != OMP_CLAUSE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - OMP_CLAUSE, 0); \ - if ((int) __t->omp_clause.code < (int) (CODE1) \ - || (int) __t->omp_clause.code > (int) (CODE2)) \ - omp_clause_range_check_failed (__t, __FILE__, __LINE__, \ - __FUNCTION__, (CODE1), (CODE2)); \ - __t; }) +#define OMP_CLAUSE_RANGE_CHECK(T, CODE1, CODE2) \ +(omp_clause_range_check ((T), (CODE1), (CODE2), \ + __FILE__, __LINE__, __FUNCTION__)) +/* ((typeof (T)) omp_clause_range_check ((T), (CODE1), (CODE2), \ + __FILE__, __LINE__, __FUNCTION__)) */ /* These checks have to be special cased. */ -#define EXPR_CHECK(T) __extension__ \ -({ __typeof (T) const __t = (T); \ - char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); \ - if (!IS_EXPR_CODE_CLASS (__c)) \ - tree_class_check_failed (__t, tcc_expression, __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) +#define EXPR_CHECK(T) \ +(expr_check ((T), __FILE__, __LINE__, __FUNCTION__)) +/* ((typeof (T)) expr_check ((T), __FILE__, __LINE__, __FUNCTION__)) */ /* These checks have to be special cased. */ -#define NON_TYPE_CHECK(T) __extension__ \ -({ __typeof (T) const __t = (T); \ - if (TYPE_P (__t)) \ - tree_not_class_check_failed (__t, tcc_type, __FILE__, __LINE__, \ - __FUNCTION__); \ - __t; }) +#define NON_TYPE_CHECK(T) \ +(non_type_check ((T), __FILE__, __LINE__, __FUNCTION__)) +/* ((typeof (T)) non_type_check ((T), __FILE__, __LINE__, __FUNCTION__)) */ -#define TREE_VEC_ELT_CHECK(T, I) __extension__ \ -(*({__typeof (T) const __t = (T); \ - const int __i = (I); \ - if (TREE_CODE (__t) != TREE_VEC) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - TREE_VEC, 0); \ - if (__i < 0 || __i >= __t->vec.length) \ - tree_vec_elt_check_failed (__i, __t->vec.length, \ - __FILE__, __LINE__, __FUNCTION__); \ - &__t->vec.a[__i]; })) +#define TREE_VEC_ELT_CHECK(T, I) \ +(*(CONST_CAST2 (tree *, typeof (T)*, \ + tree_vec_elt_check ((T), (I), __FILE__, __LINE__, __FUNCTION__)))) -#define OMP_CLAUSE_ELT_CHECK(T, I) __extension__ \ -(*({__typeof (T) const __t = (T); \ - const int __i = (I); \ - if (TREE_CODE (__t) != OMP_CLAUSE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \ - OMP_CLAUSE, 0); \ - if (__i < 0 || __i >= omp_clause_num_ops [__t->omp_clause.code]) \ - omp_clause_operand_check_failed (__i, __t, __FILE__, __LINE__, \ - __FUNCTION__); \ - &__t->omp_clause.ops[__i]; })) +#define OMP_CLAUSE_ELT_CHECK(T, I) \ +(*(omp_clause_elt_check ((T), (I), \ + __FILE__, __LINE__, __FUNCTION__))) +/* (*((typeof (T)*) omp_clause_elt_check ((T), (I), \ + __FILE__, __LINE__, __FUNCTION__))) */ /* Special checks for TREE_OPERANDs. */ -#define TREE_OPERAND_CHECK(T, I) __extension__ \ -(*({__typeof (T) const __t = EXPR_CHECK (T); \ - const int __i = (I); \ - if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) \ - tree_operand_check_failed (__i, __t, \ - __FILE__, __LINE__, __FUNCTION__); \ - &__t->exp.operands[__i]; })) +#define TREE_OPERAND_CHECK(T, I) \ +(*(CONST_CAST2 (tree*, typeof (T)*, \ + tree_operand_check ((T), (I), __FILE__, __LINE__, __FUNCTION__)))) -#define TREE_OPERAND_CHECK_CODE(T, CODE, I) __extension__ \ -(*({__typeof (T) const __t = (T); \ - const int __i = (I); \ - if (TREE_CODE (__t) != CODE) \ - tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, (CODE), 0);\ - if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) \ - tree_operand_check_failed (__i, __t, \ - __FILE__, __LINE__, __FUNCTION__); \ - &__t->exp.operands[__i]; })) +#define TREE_OPERAND_CHECK_CODE(T, CODE, I) \ +(*(tree_operand_check_code ((T), (CODE), (I), \ + __FILE__, __LINE__, __FUNCTION__))) +/* (*((typeof (T)*) tree_operand_check_code ((T), (CODE), (I), \ + __FILE__, __LINE__, __FUNCTION__))) */ /* Nodes are chained together for many purposes. Types are chained together to record them for being output to the debugger @@ -936,17 +863,15 @@ enum tree_node_structure_enum { Often lists of things are represented by TREE_LIST nodes that are chained together. */ -#define TREE_CHAIN(NODE) __extension__ \ -(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_COMMON);\ - &__t->common.chain; })) +#define TREE_CHAIN(NODE) \ +(CONTAINS_STRUCT_CHECK (NODE, TS_COMMON)->common.chain) /* In all nodes that are expressions, this is the data type of the expression. In POINTER_TYPE nodes, this is the type that the pointer points to. In ARRAY_TYPE nodes, this is the type of the elements. In VECTOR_TYPE nodes, this is the type of the elements. */ -#define TREE_TYPE(NODE) __extension__ \ -(*({__typeof (NODE) const __t = CONTAINS_STRUCT_CHECK (NODE, TS_TYPED); \ - &__t->typed.type; })) +#define TREE_TYPE(NODE) \ +(CONTAINS_STRUCT_CHECK (NODE, TS_TYPED)->typed.type) extern void tree_contains_struct_check_failed (const_tree, const enum tree_node_structure_enum, @@ -3671,6 +3596,253 @@ union GTY ((ptr_alias (union lang_tree_n struct tree_optimization_option GTY ((tag ("TS_OPTIMIZATION"))) optimization; struct tree_target_option GTY ((tag ("TS_TARGET_OPTION"))) target_option; }; + + +#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + +static inline tree +tree_check (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c) +{ + if (TREE_CODE (__t) != __c) + tree_check_failed (__t, __f, __l, __g, __c, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_not_check (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c) +{ + if (TREE_CODE (__t) == __c) + tree_not_check_failed (__t, __f, __l, __g, __c, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_check2 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_not_check2 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_check3 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_not_check3 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_check4 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_not_check4 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_check5 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) != __c1 + && TREE_CODE (__t) != __c2 + && TREE_CODE (__t) != __c3 + && TREE_CODE (__t) != __c4 + && TREE_CODE (__t) != __c5) + tree_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_not_check5 (const_tree __t, const char *__f, int __l, const char *__g, + enum tree_code __c1, enum tree_code __c2, enum tree_code __c3, + enum tree_code __c4, enum tree_code __c5) +{ + if (TREE_CODE (__t) == __c1 + || TREE_CODE (__t) == __c2 + || TREE_CODE (__t) == __c3 + || TREE_CODE (__t) == __c4 + || TREE_CODE (__t) == __c5) + tree_not_check_failed (__t, __f, __l, __g, __c1, __c2, __c3, __c4, __c5, 0); + return CONST_CAST_TREE (__t); +} + +static inline tree +contains_struct_check (const_tree __t, const enum tree_node_structure_enum __s, + const char *__f, int __l, const char *__g) +{ + if (tree_contains_struct[TREE_CODE(__t)][__s] != 1) + tree_contains_struct_check_failed (__t, __s, __f, __l, __g); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_class_check (const_tree __t, const enum tree_code_class __class, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE_CLASS (TREE_CODE(__t)) != __class) + tree_class_check_failed (__t, __class, __f, __l, __g); + return CONST_CAST_TREE (__t); +} + +static inline tree +tree_range_check (const_tree __t, + enum tree_code __code1, enum tree_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) < __code1 || TREE_CODE (__t) > __code2) + tree_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return CONST_CAST_TREE (__t); +} + +static inline tree +omp_clause_subcode_check (const_tree __t, enum omp_clause_code __code, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__t->omp_clause.code != __code) + omp_clause_check_failed (__t, __f, __l, __g, __code); + return CONST_CAST_TREE (__t); +} + +static inline tree +omp_clause_range_check (const_tree __t, + enum omp_clause_code __code1, + enum omp_clause_code __code2, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if ((int) __t->omp_clause.code < (int) __code1 + || (int) __t->omp_clause.code > (int) __code2) + omp_clause_range_check_failed (__t, __f, __l, __g, __code1, __code2); + return CONST_CAST_TREE (__t); +} + +/* These checks have to be special cased. */ +static inline tree +expr_check (const_tree __t, const char *__f, int __l, const char *__g) +{ + char const __c = TREE_CODE_CLASS (TREE_CODE (__t)); + if (!IS_EXPR_CODE_CLASS (__c)) + tree_class_check_failed (__t, tcc_expression, __f, __l, __g); + return CONST_CAST_TREE (__t); +} + +/* These checks have to be special cased. */ +static inline tree +non_type_check (const_tree __t, const char *__f, int __l, const char *__g) +{ + if (TYPE_P (__t)) + tree_not_class_check_failed (__t, tcc_type, __f, __l, __g); + return CONST_CAST_TREE (__t); +} + +static inline tree * +tree_vec_elt_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != TREE_VEC) + tree_check_failed (__t, __f, __l, __g, TREE_VEC, 0); + if (__i < 0 || __i >= __t->vec.length) + tree_vec_elt_check_failed (__i, __t->vec.length, __f, __l, __g); + return &CONST_CAST_TREE (__t)->vec.a[__i]; +} + +static inline tree * +omp_clause_elt_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != OMP_CLAUSE) + tree_check_failed (__t, __f, __l, __g, OMP_CLAUSE, 0); + if (__i < 0 || __i >= omp_clause_num_ops [__t->omp_clause.code]) + omp_clause_operand_check_failed (__i, __t, __f, __l, __g); + return &CONST_CAST_TREE (__t)->omp_clause.ops[__i]; +} + +/* Compute the number of operands in an expression node NODE. For + tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself, + otherwise it is looked up from the node's code. */ +static inline int +tree_operand_length (const_tree node) +{ + if (VL_EXP_CLASS_P (node)) + return VL_EXP_OPERAND_LENGTH (node); + else + return TREE_CODE_LENGTH (TREE_CODE (node)); +} + +/* Special checks for TREE_OPERANDs. */ +static inline tree * +tree_operand_check (const_tree __t, int __i, + const char *__f, int __l, const char *__g) +{ + const_tree __u = EXPR_CHECK (__t); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__u)) + tree_operand_check_failed (__i, __u, __f, __l, __g); + return &CONST_CAST_TREE (__u)->exp.operands[__i]; +} + +static inline tree * +tree_operand_check_code (const_tree __t, enum tree_code __code, int __i, + const char *__f, int __l, const char *__g) +{ + if (TREE_CODE (__t) != __code) + tree_check_failed (__t, __f, __l, __g, __code, 0); + if (__i < 0 || __i >= TREE_OPERAND_LENGTH (__t)) + tree_operand_check_failed (__i, __t, __f, __l, __g); + return &CONST_CAST_TREE (__t)->exp.operands[__i]; +} + +#endif /* Standard named or nameless data types of the C compiler. */ @@ -5791,18 +5963,6 @@ extern tree build_personality_function ( void init_inline_once (void); -/* Compute the number of operands in an expression node NODE. For - tcc_vl_exp nodes like CALL_EXPRs, this is stored in the node itself, - otherwise it is looked up from the node's code. */ -static inline int -tree_operand_length (const_tree node) -{ - if (VL_EXP_CLASS_P (node)) - return VL_EXP_OPERAND_LENGTH (node); - else - return TREE_CODE_LENGTH (TREE_CODE (node)); -} - /* Abstract iterators for CALL_EXPRs. These static inline definitions have to go towards the end of tree.h so that union tree_node is fully defined by this point. */ -- This patch is available for review at http://codereview.appspot.com/5132047