+static const char *firm_vrfy_failure_msg;
+
+#ifdef NDEBUG
+/*
+ * in RELEASE mode, returns ret if the expression expr evaluates to zero
+ * in ASSERT mode, asserts the expression expr (and the string string).
+ */
+#define ASSERT_AND_RET(expr, string, ret) if (!(expr)) return (ret)
+
+/*
+ * in RELEASE mode, returns ret if the expression expr evaluates to zero
+ * in ASSERT mode, executes blk if the expression expr evaluates to zero and asserts expr
+ */
+#define ASSERT_AND_RET_DBG(expr, string, ret, blk) if (!(expr)) return (ret)
+#else
+#define ASSERT_AND_RET(expr, string, ret) \
+do { \
+ if (opt_do_node_verification == FIRM_VERIFICATION_ON) {\
+ assert((expr) && string); } \
+ if (!(expr)) { \
+ if (opt_do_node_verification == FIRM_VERIFICATION_REPORT) \
+ fprintf(stderr, #expr " : " string "\n"); \
+ firm_vrfy_failure_msg = #expr " && " string; \
+ return (ret); \
+ } \
+} while(0)
+
+#define ASSERT_AND_RET_DBG(expr, string, ret, blk) \
+do { \
+ if (!(expr)) { \
+ firm_vrfy_failure_msg = #expr " && " string; \
+ if (opt_do_node_verification != FIRM_VERIFICATION_ERROR_ONLY) { blk; } \
+ if (opt_do_node_verification == FIRM_VERIFICATION_REPORT) \
+ fprintf(stderr, #expr " : " string "\n"); \
+ else if (opt_do_node_verification == FIRM_VERIFICATION_ON) { \
+ assert((expr) && string); \
+ } \
+ return (ret); \
+ } \
+} while(0)
+
+#endif /* NDEBUG */
+
+/**
+ * Show diagnostic if an entity overwrites another one not
+ * in direct superclasses.
+ */
+static void show_ent_not_supertp(entity *ent, entity *ovw)
+{
+ ir_type *owner = get_entity_owner(ent);
+ ir_type *ov_own = get_entity_owner(ovw);
+ int i;
+
+ fprintf(stderr, "Type verification error:\n");
+ ir_fprintf(stderr, "Entity %+F::%+e owerwrites ", owner, ent);
+ ir_fprintf(stderr, "Entity %+F::%+e\n", ov_own, ovw);
+
+ ir_fprintf(stderr, "Supertypes of %+F:\n", owner);
+ for (i = 0; i < get_class_n_supertypes(owner); ++i) {
+ ir_type *super = get_class_supertype(owner, i);
+ ir_fprintf(stderr, " %+F:\n", super);
+ }
+}
+
+/**
+ * Show diagnostic if an entity owerwrites a wrong number of things.
+ */
+static void show_ent_overwrite_cnt(entity *ent)
+{
+ ir_type *owner = get_entity_owner(ent);
+ int i, j, k, found, show_stp = 0;
+
+ fprintf(stderr, "Type verification error:\n");
+ ir_fprintf(stderr, "Entity %+F::%+e owerwrites\n", owner, ent);
+ for (i = 0; i < get_entity_n_overwrites(ent); ++i) {
+ entity *ovw = get_entity_overwrites(ent, i);
+ ir_type *ov_own = get_entity_owner(ovw);
+
+ for (k = 0; k < i; ++k)
+ if (ovw == get_entity_overwrites(ent, k)) {
+ ir_fprintf(stderr, " %+F::%+e entered more than once\n", ov_own, ovw);
+ break;
+ }
+
+ found = 0;
+ for (j = get_class_n_supertypes(owner) - 1; j >= 0; --j) {
+ if (ov_own == get_class_supertype(owner, j)) {
+ show_stp = found = 1;
+ break;
+ }
+ }
+ if (! found)
+ ir_fprintf(stderr, " %+F::%+e not in super types of %t\n", ov_own, ovw, owner);
+ }
+
+ if (show_stp) {
+ ir_fprintf(stderr, "Supertypes of %+F:\n", owner);
+ for (i = 0; i < get_class_n_supertypes(owner); ++i) {
+ ir_type *super = get_class_supertype(owner, i);
+ ir_fprintf(stderr, " %+F:\n", super);
+ }
+ }
+}
+
+/**
+ * Check a class
+ */
+static int check_class(ir_type *tp) {