/* Language-specific tree checkers. */
-#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+#define VAR_OR_FUNCTION_DECL_CHECK(NODE) \
+ TREE_CHECK2(NODE,VAR_DECL,FUNCTION_DECL)
-#define VAR_OR_FUNCTION_DECL_CHECK(NODE) __extension__ \
-({ const tree __t = (NODE); \
- enum tree_code const __c = TREE_CODE(__t); \
- if (__c != VAR_DECL && __c != FUNCTION_DECL) \
- tree_check_failed (__t, VAR_DECL, __FILE__, __LINE__, \
- __FUNCTION__); \
- __t; })
-
-#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) __extension__ \
-({ const tree __t = (NODE); \
- enum tree_code const __c = TREE_CODE(__t); \
- if (__c != VAR_DECL \
- && __c != FUNCTION_DECL \
- && __c != PARM_DECL) \
- tree_check_failed (__t, VAR_DECL, __FILE__, __LINE__, \
- __FUNCTION__); \
- __t; })
-
-#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) __extension__ \
-({ const tree __t = (NODE); \
- enum tree_code const __c = TREE_CODE(__t); \
- if (__c != VAR_DECL \
- && __c != FUNCTION_DECL \
- && __c != TYPE_DECL \
- && __c != TEMPLATE_DECL) \
- tree_check_failed (__t, VAR_DECL, __FILE__, __LINE__, \
- __FUNCTION__); \
- __t; })
-
-#define RECORD_OR_UNION_TYPE_CHECK(NODE) __extension__ \
-({ const tree __t = (NODE); \
- enum tree_code const __c = TREE_CODE(__t); \
- if (__c != RECORD_TYPE && __c != UNION_TYPE) \
- tree_check_failed (__t, RECORD_TYPE, __FILE__, __LINE__, \
- __FUNCTION__); \
- __t; })
-
-#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) __extension__ \
-({ const tree __t = (NODE); \
- enum tree_code const __c = TREE_CODE(__t); \
- if (__c != BOUND_TEMPLATE_TEMPLATE_PARM) \
- tree_check_failed (__t, BOUND_TEMPLATE_TEMPLATE_PARM, \
- __FILE__, __LINE__, __FUNCTION__); \
- __t; })
-
-#else /* not ENABLE_TREE_CHECKING, or not gcc */
-
-#define VAR_OR_FUNCTION_DECL_CHECK(NODE) (NODE)
-#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) (NODE)
-#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) (NODE)
-#define RECORD_OR_UNION_TYPE_CHECK(NODE) (NODE)
-#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) (NODE)
+#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) \
+ TREE_CHECK3(NODE,VAR_DECL,FUNCTION_DECL,PARM_DECL)
-#endif
+#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) \
+ TREE_CHECK4(NODE,VAR_DECL,FUNCTION_DECL,TYPE_DECL,TEMPLATE_DECL)
+
+#define RECORD_OR_UNION_TYPE_CHECK(NODE) \
+ TREE_CHECK2(NODE,RECORD_TYPE,UNION_TYPE)
+
+#define BOUND_TEMPLATE_TEMPLATE_PARM_TYPE_CHECK(NODE) \
+ TREE_CHECK(NODE,BOUND_TEMPLATE_TEMPLATE_PARM)
\f
/* Language-dependent contents of an identifier. */
\f
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
-/* Complain that the tree code of NODE does not match the expected CODE.
- FILE, LINE, and FUNCTION are of the caller. */
+/* Complain that the tree code of NODE does not match the expected 0
+ terminated list of trailing codes. FILE, LINE, and FUNCTION are of
+ the caller. */
void
-tree_check_failed (const tree node, enum tree_code code, const char *file,
- int line, const char *function)
-{
+tree_check_failed (const tree node, const char *file,
+ int line, const char *function, ...)
+{
+ va_list args;
+ char *buffer;
+ unsigned length = 0;
+ int code;
+
+ va_start (args, function);
+ while ((code = va_arg (args, int)))
+ length += 4 + strlen (tree_code_name[code]);
+ va_end (args);
+ va_start (args, function);
+ buffer = alloca (length);
+ length = 0;
+ while ((code = va_arg (args, int)))
+ {
+ if (length)
+ {
+ strcpy (buffer + length, " or ");
+ length += 4;
+ }
+ strcpy (buffer + length, tree_code_name[code]);
+ length += strlen (tree_code_name[code]);
+ }
+ va_end (args);
+
internal_error ("tree check: expected %s, have %s in %s, at %s:%d",
- tree_code_name[code], tree_code_name[TREE_CODE (node)],
- function, trim_filename (file), line);
-}
-
-/* Similar to above except that we allowed the code to be one of two
- different codes. */
-
-void
-tree_check2_failed (const tree node, enum tree_code code1,
- enum tree_code code2, const char *file,
- int line, const char *function)
-{
- internal_error ("tree check: expected %s or %s, have %s in %s, at %s:%d",
- tree_code_name[code1], tree_code_name[code2],
- tree_code_name[TREE_CODE (node)],
+ buffer, tree_code_name[TREE_CODE (node)],
function, trim_filename (file), line);
}
-/* Likewise for three different codes. */
+/* Complain that the tree code of NODE does match the expected 0
+ terminated list of trailing codes. FILE, LINE, and FUNCTION are of
+ the caller. */
void
-tree_check3_failed (const tree node, enum tree_code code1,
- enum tree_code code2, enum tree_code code3,
- const char *file, int line, const char *function)
-{
- internal_error ("tree check: expected %s, %s or %s; have %s in %s, at %s:%d",
- tree_code_name[code1], tree_code_name[code2],
- tree_code_name[code3], tree_code_name[TREE_CODE (node)],
+tree_not_check_failed (const tree node, const char *file,
+ int line, const char *function, ...)
+{
+ va_list args;
+ char *buffer;
+ unsigned length = 0;
+ int code;
+
+ va_start (args, function);
+ while ((code = va_arg (args, int)))
+ length += 4 + strlen (tree_code_name[code]);
+ va_end (args);
+ va_start (args, function);
+ buffer = alloca (length);
+ length = 0;
+ while ((code = va_arg (args, int)))
+ {
+ if (length)
+ {
+ strcpy (buffer + length, " or ");
+ length += 4;
+ }
+ strcpy (buffer + length, tree_code_name[code]);
+ length += strlen (tree_code_name[code]);
+ }
+ va_end (args);
+
+ internal_error ("tree check: expected none of %s, have %s in %s, at %s:%d",
+ buffer, tree_code_name[TREE_CODE (node)],
function, trim_filename (file), line);
}
-/* ... and for four different codes. */
-
-void
-tree_check4_failed (const tree node, enum tree_code code1,
- enum tree_code code2, enum tree_code code3,
- enum tree_code code4, const char *file, int line,
- const char *function)
-{
- internal_error
- ("tree check: expected %s, %s, %s or %s; have %s in %s, at %s:%d",
- tree_code_name[code1], tree_code_name[code2], tree_code_name[code3],
- tree_code_name[code4], tree_code_name[TREE_CODE (node)], function,
- trim_filename (file), line);
-}
-
-/* ... and for five different codes. */
-
-void
-tree_check5_failed (const tree node, enum tree_code code1,
- enum tree_code code2, enum tree_code code3,
- enum tree_code code4, enum tree_code code5,
- const char *file, int line, const char *function)
-{
- internal_error
- ("tree check: expected %s, %s, %s, %s or %s; have %s in %s, at %s:%d",
- tree_code_name[code1], tree_code_name[code2], tree_code_name[code3],
- tree_code_name[code4], tree_code_name[code5],
- tree_code_name[TREE_CODE (node)], function, trim_filename (file), line);
-}
-
/* Similar to tree_check_failed, except that we check for a class of tree
code, given in CL. */
#define TREE_CHECK(T, CODE) __extension__ \
({ const tree __t = (T); \
if (TREE_CODE (__t) != (CODE)) \
- tree_check_failed (__t, (CODE), __FILE__, __LINE__, __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE), 0); \
+ __t; })
+
+#define TREE_NOT_CHECK(T, CODE) __extension__ \
+({ const tree __t = (T); \
+ if (TREE_CODE (__t) == (CODE)) \
+ tree_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE), 0); \
__t; })
#define TREE_CHECK2(T, CODE1, CODE2) __extension__ \
({ const tree __t = (T); \
if (TREE_CODE (__t) != (CODE1) \
&& TREE_CODE (__t) != (CODE2)) \
- tree_check2_failed (__t, (CODE1), (CODE2), __FILE__, __LINE__, \
- __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE1), (CODE2), 0); \
+ __t; })
+
+#define TREE_NOT_CHECK2(T, CODE1, CODE2) __extension__ \
+({ const tree __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_CHECK3(T, CODE1, CODE2, CODE3) __extension__ \
if (TREE_CODE (__t) != (CODE1) \
&& TREE_CODE (__t) != (CODE2) \
&& TREE_CODE (__t) != (CODE3)) \
- tree_check3_failed (__t, (CODE1), (CODE2), (CODE3), __FILE__, \
- __LINE__, __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE1), (CODE2), (CODE3), 0); \
+ __t; })
+
+#define TREE_NOT_CHECK3(T, CODE1, CODE2, CODE3) __extension__ \
+({ const tree __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_CHECK4(T, CODE1, CODE2, CODE3, CODE4) __extension__ \
&& TREE_CODE (__t) != (CODE2) \
&& TREE_CODE (__t) != (CODE3) \
&& TREE_CODE (__t) != (CODE4)) \
- tree_check4_failed (__t, (CODE1), (CODE2), (CODE3), (CODE4), \
- __FILE__, __LINE__, __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE1), (CODE2), (CODE3), (CODE4), 0); \
+ __t; })
+
+#define NON_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_not_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE1), (CODE2), (CODE3), (CODE4), 0); \
__t; })
#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) __extension__ \
&& TREE_CODE (__t) != (CODE3) \
&& TREE_CODE (__t) != (CODE4) \
&& TREE_CODE (__t) != (CODE5)) \
- tree_check5_failed (__t, (CODE1), (CODE2), (CODE3), (CODE4), \
- (CODE5), __FILE__, __LINE__, __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ (CODE1), (CODE2), (CODE3), (CODE4), (CODE5), 0);\
+ __t; })
+
+#define TREE_NOT_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) __extension__ \
+({ const tree __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_CLASS_CHECK(T, CLASS) __extension__ \
(*({const tree __t = (T); \
const int __i = (I); \
if (TREE_CODE (__t) != TREE_VEC) \
- tree_check_failed (__t, TREE_VEC, \
- __FILE__, __LINE__, __FUNCTION__); \
+ 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__); \
(*({const tree __t = t; \
const int __i = (i); \
if (TREE_CODE (__t) != PHI_NODE) \
- tree_check_failed (__t, PHI_NODE, \
- __FILE__, __LINE__, __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, \
+ PHI_NODE, 0); \
if (__i < 0 || __i >= __t->phi.capacity) \
phi_node_elt_check_failed (__i, __t->phi.num_args, \
__FILE__, __LINE__, __FUNCTION__); \
(*({const tree __t = (T); \
const int __i = (I); \
if (TREE_CODE (__t) != CODE) \
- tree_check_failed (__t, CODE, __FILE__, __LINE__, __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, (CODE), 0);\
if (__i < 0 || __i >= TREE_CODE_LENGTH (CODE)) \
tree_operand_check_failed (__i, (CODE), \
__FILE__, __LINE__, __FUNCTION__); \
({const tree __t = (T); \
const int __i = (I); \
if (TREE_CODE (__t) != (CODE)) \
- tree_check_failed (__t, (CODE), __FILE__, __LINE__, __FUNCTION__); \
+ tree_check_failed (__t, __FILE__, __LINE__, __FUNCTION__, (CODE), 0); \
if (__i < 0 || __i >= TREE_CODE_LENGTH ((CODE))) \
tree_operand_check_failed (__i, (CODE), \
__FILE__, __LINE__, __FUNCTION__); \
&__t->exp.operands[__i]; }))
-extern void tree_check_failed (const tree, enum tree_code,
- const char *, int, const char *)
- ATTRIBUTE_NORETURN;
-extern void tree_check2_failed (const tree, enum tree_code, enum tree_code,
- const char *, int, const char *)
- ATTRIBUTE_NORETURN;
-extern void tree_check3_failed (const tree, enum tree_code, enum tree_code,
- 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 *)
- ATTRIBUTE_NORETURN;
+extern void tree_check_failed (const tree, const char *, int, const char *,
+ ...) ATTRIBUTE_NORETURN;
+extern void tree_not_check_failed (const tree, const char *, int, const char *,
+ ...) ATTRIBUTE_NORETURN;
extern void tree_class_check_failed (const tree, int,
const char *, int, const char *)
ATTRIBUTE_NORETURN;
#else /* not ENABLE_TREE_CHECKING, or not gcc */
#define TREE_CHECK(T, CODE) (T)
+#define TREE_NOT_CHECK(T, CODE) (T)
#define TREE_CHECK2(T, CODE1, CODE2) (T)
+#define TREE_NOT_CHECK2(T, CODE1, CODE2) (T)
#define TREE_CHECK3(T, CODE1, CODE2, CODE3) (T)
+#define TREE_NOT_CHECK3(T, CODE1, CODE2, CODE3) (T)
#define TREE_CHECK4(T, CODE1, CODE2, CODE3, CODE4) (T)
+#define TREE_NOT_CHECK4(T, CODE1, CODE2, CODE3, CODE4) (T)
#define TREE_CHECK5(T, CODE1, CODE2, CODE3, CODE4, CODE5) (T)
+#define TREE_NOT_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)