refactored tagging support


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@307 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/ChangeLog b/ChangeLog
index fd99b96..9725d7f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,11 @@
 
-0.9.4:	2004-Sep-07
+0.9.4:	2004-Sep-10
 
 	* More support for recursive type definitions.
 	* Explicit support for ANY type decoding.
+	* Refactored tags processing code.
+	* Fixed constraints checking code: non-exploitable buffer overflow.
+	  (Severity: medium, Security impact: low)
 
 0.9.3:	2004-Sep-07
 
diff --git a/asn1c/tests/check-43.c b/asn1c/tests/check-43.c
index c906f64..bb5c219 100644
--- a/asn1c/tests/check-43.c
+++ b/asn1c/tests/check-43.c
@@ -6,18 +6,17 @@
 #include <assert.h>
 
 #include <Test-structure-1.h>
-#include <Sets.h>
+#include <Choice-1.h>
 
 int
 main(int ac, char **av) {
 	Test_structure_1_t ts1;
-	Sets_t s1;
+	Choice_1_t cs1;
 
 	(void)ac;	/* Unused argument */
 	(void)av;	/* Unused argument */
 
 	memset(&ts1, 0, sizeof(ts1));
-	memset(&s1, 0, sizeof(s1));
 
 	/*
 	 * No plans to fill it up: just checking whether it compiles or not.
diff --git a/asn1c/tests/check-65.c b/asn1c/tests/check-65.c
new file mode 100644
index 0000000..65078e2
--- /dev/null
+++ b/asn1c/tests/check-65.c
@@ -0,0 +1,115 @@
+#undef	NDEBUG
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <string.h>
+#include <assert.h>
+
+#include <T.h>
+#include <T1.h>
+
+uint8_t buf1[] = {
+	32 | ((2 << 6) + 2),	/* [2], constructed */
+	8,
+	32 | ((2 << 6) + 3),	/* [3], constructed */
+	6,
+	32 | ((2 << 6) + 4),	/* [4], constructed */
+	4,
+	0  | ((2 << 6) + 6),	/* [6], primitive */
+	2,
+  0x91,
+  0x92
+};
+
+uint8_t buf2[] = {
+
+	32 | ((2 << 6) + 0),	/* [0], constructed */
+	22,
+
+	32 | ((2 << 6) + 1),	/* [1], constructed */
+	6,
+	32 | ((2 << 6) + 4),	/* [4], constructed */
+	4,
+	0  | ((2 << 6) + 6),	/* [6], primitive */
+	2,
+  0x91,
+  0x92,
+
+	32 | ((2 << 6) + 2),	/* [2], constructed */
+	6,
+	32 | ((2 << 6) + 4),	/* [4], constructed */
+	4,
+	0  | ((2 << 6) + 6),	/* [6], primitive */
+	2,
+  0x91,
+  0x92,
+
+	32 | ((2 << 6) + 3),	/* [3], constructed */
+	4,
+	0  | ((2 << 6) + 6),	/* [6], primitive */
+	2,
+  0x91,
+  0x92,
+
+};
+
+static void
+check_1(int is_ok, uint8_t *buf, int size, size_t consumed) {
+	asn1_TYPE_descriptor_t *td = &asn1_DEF_T1;
+	ber_dec_rval_t rval;
+	T1_t t, *tp;
+
+	tp = memset(&t, 0, sizeof(t));
+
+	fprintf(stderr, "Buf %p\n", buf);
+	rval = ber_decode(td, (void **)&tp, buf, size);
+	fprintf(stderr, "Returned code %d, consumed %d\n",
+		(int)rval.code, (int)rval.consumed);
+
+	if(is_ok) {
+		assert(rval.code == RC_OK);
+		assert(rval.consumed == consumed);
+	} else {
+		if(rval.code == RC_OK) {
+		}
+		assert(rval.consumed <= consumed);
+	}
+}
+
+static void
+check_2(int is_ok, uint8_t *buf, int size, size_t consumed) {
+	asn1_TYPE_descriptor_t *td = &asn1_DEF_T;
+	ber_dec_rval_t rval;
+	T_t t, *tp;
+
+	tp = memset(&t, 0, sizeof(t));
+
+	fprintf(stderr, "Buf %p\n", buf);
+	rval = ber_decode(td, (void **)&tp, buf, size);
+	fprintf(stderr, "Returned code %d, consumed %d\n",
+		(int)rval.code, (int)rval.consumed);
+
+	if(is_ok) {
+		assert(rval.code == RC_OK);
+		assert(rval.consumed == consumed);
+	} else {
+		if(rval.code == RC_OK) {
+		}
+		assert(rval.consumed <= consumed);
+	}
+}
+
+int
+main(int ac, char **av) {
+
+	(void)ac;	/* Unused argument */
+	(void)av;	/* Unused argument */
+
+	check_1(1, buf1, sizeof(buf1), sizeof(buf1));
+	check_1(0, buf1, sizeof(buf1) - 1, sizeof(buf1) - 1);
+
+	check_2(1, buf2, sizeof(buf2), sizeof(buf2));
+	check_2(0, buf2, sizeof(buf2) - 1, sizeof(buf2) - 1);
+
+	return 0;
+}
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 00b278b..c448795 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -29,7 +29,7 @@
 static int expr_better_indirect(arg_t *arg, asn1p_expr_t *expr);
 static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
 static int emit_member_table(arg_t *arg, asn1p_expr_t *expr);
-static int emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode);
+static int emit_tags_vector(arg_t *arg, asn1p_expr_t *expr);
 static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count);
 
 enum etd_cp {
@@ -42,7 +42,7 @@
 	ETD_NO_SPECIFICS,
 	ETD_HAS_SPECIFICS
 };
-static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, int tags_count, int tags_impl_skip, int elements_count, enum etd_cp, enum etd_spec);
+static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, int tags_count, int elements_count, enum etd_cp, enum etd_spec);
 
 #define	C99_MODE	(!(arg->flags & A1C_NO_C99))
 #define	UNNAMED_UNIONS	(arg->flags & A1C_UNNAMED_UNIONS)
@@ -169,7 +169,6 @@
 	asn1p_expr_t *expr = arg->expr;
 	asn1p_expr_t *v;
 	int elements;	/* Number of elements */
-	int tags_impl_skip = 0;
 	int comp_mode = 0;	/* {root,ext=1,root,root,...} */
 	int ext_start = -1;
 	int ext_stop = -1;
@@ -215,7 +214,7 @@
 	/*
 	 * Print out asn1_DEF_<type>_tags[] vector.
 	 */
-	tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
+	tags_count = emit_tags_vector(arg, expr);
 
 	/*
 	 * Tags to elements map.
@@ -239,7 +238,7 @@
 	/*
 	 * Emit asn1_DEF_xxx table.
 	 */
-	emit_type_DEF(arg, expr, tags_count, tags_impl_skip, elements,
+	emit_type_DEF(arg, expr, tags_count, elements,
 			ETD_CP_CONSTRUCTED, ETD_HAS_SPECIFICS);
 
 	REDIR(OT_TYPE_DECLS);
@@ -319,7 +318,6 @@
 	asn1p_expr_t *expr = arg->expr;
 	asn1p_expr_t *v;
 	int elements;
-	int tags_impl_skip = 0;
 	int comp_mode = 0;	/* {root,ext=1,root,root,...} */
 	tag2el_t *tag2el = NULL;
 	int tag2el_count = 0;
@@ -363,7 +361,7 @@
 	/*
 	 * Print out asn1_DEF_<type>_tags[] vector.
 	 */
-	tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
+	tags_count = emit_tags_vector(arg, expr);
 
 	/*
 	 * Tags to elements map.
@@ -419,7 +417,7 @@
 	/*
 	 * Emit asn1_DEF_xxx table.
 	 */
-	emit_type_DEF(arg, expr, tags_count, tags_impl_skip, elements,
+	emit_type_DEF(arg, expr, tags_count, elements,
 			ETD_CP_CONSTRUCTED, ETD_HAS_SPECIFICS);
 
 	REDIR(OT_TYPE_DECLS);
@@ -484,7 +482,6 @@
 asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
 	asn1p_expr_t *expr = arg->expr;
 	asn1p_expr_t *v;
-	int tags_impl_skip = 0;
 	int tags_count;
 	char *p;
 
@@ -516,7 +513,7 @@
 	/*
 	 * Print out asn1_DEF_<type>_tags[] vector.
 	 */
-	tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
+	tags_count = emit_tags_vector(arg, expr);
 
 	p = MKID(expr->Identifier);
 	OUT("static asn1_SET_OF_specifics_t asn1_DEF_%s_specs = {\n", p);
@@ -529,7 +526,7 @@
 	/*
 	 * Emit asn1_DEF_xxx table.
 	 */
-	emit_type_DEF(arg, expr, tags_count, tags_impl_skip, 1,
+	emit_type_DEF(arg, expr, tags_count, 1,
 			ETD_CP_CONSTRUCTED, ETD_HAS_SPECIFICS);
 
 	REDIR(OT_TYPE_DECLS);
@@ -599,7 +596,6 @@
 	asn1p_expr_t *expr = arg->expr;
 	asn1p_expr_t *v;
 	int elements;	/* Number of elements */
-	int tags_impl_skip = 0;
 	int comp_mode = 0;	/* {root,ext=1,root,root,...} */
 	tag2el_t *tag2el = NULL;
 	int tag2el_count = 0;
@@ -647,7 +643,7 @@
 		 */
 		tags_count = 0;
 	} else {
-		tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 1);
+		tags_count = emit_tags_vector(arg, expr);
 	}
 
 	/*
@@ -672,7 +668,7 @@
 	/*
 	 * Emit asn1_DEF_xxx table.
 	 */
-	emit_type_DEF(arg, expr, tags_count, tags_impl_skip, elements,
+	emit_type_DEF(arg, expr, tags_count, elements,
 			ETD_CP_CONSTRUCTED /*either?!*/, ETD_HAS_SPECIFICS);
 
 	REDIR(OT_TYPE_DECLS);
@@ -727,7 +723,6 @@
 int
 asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
 	asn1p_expr_t *expr = arg->expr;
-	int tags_impl_skip = 0;
 	int tags_count;
 	char *p;
 
@@ -761,9 +756,9 @@
 	/*
 	 * Print out asn1_DEF_<type>_tags[] vector.
 	 */
-	tags_count = emit_tags_vector(arg, expr, &tags_impl_skip, 0);
+	tags_count = emit_tags_vector(arg, expr);
 
-	emit_type_DEF(arg, expr, tags_count, tags_impl_skip, 0,
+	emit_type_DEF(arg, expr, tags_count, 0,
 			ETD_CP_UNKNOWN, ETD_NO_SPECIFICS);
 
 	REDIR(OT_CODE);
@@ -814,11 +809,18 @@
 	OUT("%s_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {\n", p);
 	INDENT(+1);
 	{
+	asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, arg->mod, expr);
 	char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
 	OUT("td->ber_decoder    = asn1_DEF_%s.ber_decoder;\n",    type_name);
 	OUT("td->der_encoder    = asn1_DEF_%s.der_encoder;\n",    type_name);
 	OUT("td->free_struct    = asn1_DEF_%s.free_struct;\n",    type_name);
 	OUT("td->print_struct   = asn1_DEF_%s.print_struct;\n",   type_name);
+	if(!terminal && !tags_count) {
+	  OUT("/* The next two lines are because of -fknown-extern-type */\n");
+	  OUT("td->tags           = asn1_DEF_%s.tags;\n",         type_name);
+	  OUT("td->tags_count     = asn1_DEF_%s.tags_count;\n",   type_name);
+	  OUT("/* End of these lines */\n");
+	}
 	OUT("td->last_tag_form  = asn1_DEF_%s.last_tag_form;\n",  type_name);
 	OUT("td->elements       = asn1_DEF_%s.elements;\n",       type_name);
 	OUT("td->elements_count = asn1_DEF_%s.elements_count;\n", type_name);
@@ -834,8 +836,7 @@
 	INDENTED(
 	OUT("\tvoid **structure, void *bufptr, size_t size, int tag_mode) {\n");
 	OUT("%s_inherit_TYPE_descriptor(td);\n", p);
-	OUT("return td->ber_decoder(td, structure,\n");
-	OUT("\tbufptr, size, tag_mode);\n");
+	OUT("return td->ber_decoder(td, structure, bufptr, size, tag_mode);\n");
 	);
 	OUT("}\n");
 	OUT("\n");
@@ -1122,56 +1123,31 @@
 }
 
 static int
-emit_tags_vector(arg_t *arg, asn1p_expr_t *expr, int *tags_impl_skip, int choice_mode) {
+emit_tags_vector(arg_t *arg, asn1p_expr_t *expr) {
+	struct asn1p_type_tag_s *tags = 0;
 	int tags_count = 0;
-	int save_target = arg->target->target;
-	char *p;
+	int i;
 
-	if(save_target != OT_IGNORE) {
-		int save_impl_skip = *tags_impl_skip;
-		REDIR(OT_IGNORE);
-		tags_count = emit_tags_vector(arg, expr,
-			tags_impl_skip, choice_mode);
-		REDIR(save_target);
-		if(tags_count) {
-			*tags_impl_skip = save_impl_skip;
-			tags_count = 0;
-		} else {
-			return 0;
-		}
-	}
-			
+	/* Fetch a chain of tags */
+	tags_count = asn1f_fetch_tags(arg->asn, arg->mod, expr, &tags, 0);
+	if(tags_count <= 0)
+		return 0;
 
-	p = MKID(expr->Identifier);
-	OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n", p);
+	OUT("static ber_tlv_tag_t asn1_DEF_%s_tags[] = {\n",
+		MKID(expr->Identifier));
 	INDENT(+1);
-	if(expr->tag.tag_class) {
-		tags_count++;
-		_print_tag(arg, &expr->tag);
-		if(expr->tag.tag_mode != TM_EXPLICIT)
-			(*tags_impl_skip)++;
-	} else {
-		if(!choice_mode)
-			(*tags_impl_skip)++;
+
+	/* Print the array of collected tags */
+	for(i = 0; i < tags_count; i++) {
+		if(i) OUT(",\n");
+		_print_tag(arg, &tags[i]);
 	}
-	if(!choice_mode) {
-		if(!expr->tag.tag_class
-		|| (expr->meta_type == AMT_TYPE
-			&& expr->tag.tag_mode == TM_EXPLICIT)) {
-			struct asn1p_type_tag_s tag;
-			if(expr->tag.tag_class)
-				OUT(",\n");
-			tag.tag_class = TC_UNIVERSAL;
-			tag.tag_mode = TM_IMPLICIT;
-			tag.tag_value = expr_type2uclass_value[expr->expr_type];
-			_print_tag(arg, &tag);
-			tags_count++;
-		}
-	}
+
 	OUT("\n");
 	INDENT(-1);
 	OUT("};\n");
 
+	free(tags);
 	return tags_count;
 }
 
@@ -1317,7 +1293,7 @@
 }
 
 static int
-emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, int tags_count, int tags_impl_skip, int elements_count, enum etd_cp cp, enum etd_spec spec) {
+emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, int tags_count, int elements_count, enum etd_cp cp, enum etd_spec spec) {
 	char *p;
 
 	p = MKID(expr->Identifier);
@@ -1355,7 +1331,6 @@
 			OUT("0,\t/* No explicit tags (count) */\n");
 		}
 
-		OUT("%d,\t/* Tags to skip */\n", tags_impl_skip);
 		switch(cp) {
 		case ETD_CP_UNKNOWN:
 			OUT("-0,\t/* Unknown yet */\n");
diff --git a/libasn1fix/asn1fix_internal.h b/libasn1fix/asn1fix_internal.h
index c373963..040750d 100644
--- a/libasn1fix/asn1fix_internal.h
+++ b/libasn1fix/asn1fix_internal.h
@@ -89,7 +89,7 @@
 		if(code < 0) {					\
 			if(arg->debug)				\
 				arg->debug(code, fmt, ##args);	\
-		} else {					\
+		} else if(arg->eh) {				\
 			arg->eh(code, fmt " in %s", ##args,	\
 				arg->mod->source_file_name);	\
 		}						\
diff --git a/libasn1fix/asn1fix_tags.c b/libasn1fix/asn1fix_tags.c
index 20066e6..6d88798 100644
--- a/libasn1fix/asn1fix_tags.c
+++ b/libasn1fix/asn1fix_tags.c
@@ -2,14 +2,20 @@
 
 #define	ADD_TAG(skip, newtag)	do {					\
 	void *__p;							\
-	if(skip) { skip--; break; }					\
+	if(skip) {							\
+		if(newtag.tag_mode != TM_IMPLICIT)			\
+			skip--;						\
+		break;							\
+	} else {							\
+		if(newtag.tag_mode == TM_IMPLICIT)			\
+			skip++;						\
+	}								\
 	__p = realloc((*tags),						\
 		sizeof(struct asn1p_type_tag_s) * (count + 1));		\
 	if(!__p) return -1;						\
 	*tags = __p;							\
 	(*tags)[count++] = newtag;					\
 	if((flags & AFT_FETCH_OUTMOST)) return count;			\
-	if(newtag.tag_mode == TM_IMPLICIT) skip++;			\
 } while(0)
 
 static int
@@ -46,11 +52,33 @@
 	}
 
 	if(expr->meta_type == AMT_TYPEREF) {
-		expr = asn1f_lookup_symbol(arg, expr->module, expr->reference);
-		if(expr == NULL) return -1;
+		asn1p_expr_t *nexpr;
+		nexpr = asn1f_lookup_symbol(arg, expr->module, expr->reference);
+		if(nexpr == NULL) {
+			if(errno != EEXIST)	/* -fknown-extern-type */
+				return -1;
+			if(!count)
+				return 0;	/* OK */
+			if((*tags)[count-1].tag_mode == TM_IMPLICIT) {
+				WARNING("Tagging mode for %s "
+					"is IMPLICIT, assuming %s "
+					"has exactly one tag",
+					expr->Identifier,
+					asn1f_printable_reference(expr->reference)
+				);
+				return count;
+			}
+			FATAL("Tagging mode %s -> %s "
+				"dangerously incompatible",
+				expr->Identifier,
+				asn1f_printable_reference(expr->reference)
+			);
+			return -1;
+		} else {
+			arg->expr = nexpr;
+		}
 		if(expr->_mark & TM_RECURSION)
 			return -1;
-		arg->expr = expr;
 		expr->_mark |= TM_RECURSION;
 		count = asn1f_fetch_tags_impl(arg, tags, count, skip, flags);
 		expr->_mark &= ~TM_RECURSION;
diff --git a/libasn1fix/asn1fix_tags.h b/libasn1fix/asn1fix_tags.h
index 8dd622b..394c3e8 100644
--- a/libasn1fix/asn1fix_tags.h
+++ b/libasn1fix/asn1fix_tags.h
@@ -6,7 +6,6 @@
 	AFT_FETCH_OUTMOST	= 0x02,	/* Fetch only outmost tag */
 };
 
-
 /*
  * Allocate and return an array of tags for the given type.
  * Type1 ::= [2] EXPLICIT Type2
diff --git a/skeletons/ANY.c b/skeletons/ANY.c
index 2057120..92b209d 100644
--- a/skeletons/ANY.c
+++ b/skeletons/ANY.c
@@ -15,7 +15,6 @@
 	OCTET_STRING_free,
 	0, /* Use generic outmost tag fetcher */
 	0,
-	0,
 	0,	/* No tags may be overridden */
 	-1,	/* Both ways are fine (primitive and constructed) */
 	0, 0,	/* No members */
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index bca3473..7f1aa09 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -21,7 +21,6 @@
 	asn1_DEF_BIT_STRING_tags,
 	sizeof(asn1_DEF_BIT_STRING_tags)
 	  / sizeof(asn1_DEF_BIT_STRING_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	(void *)-1	/* Special indicator that this is a BIT STRING */
diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c
index 6b3ceeb..87aacea 100644
--- a/skeletons/BMPString.c
+++ b/skeletons/BMPString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_BMPString_tags,
 	sizeof(asn1_DEF_BMPString_tags)
 	  / sizeof(asn1_DEF_BMPString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index b0ae178..b7b4795 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -20,7 +20,6 @@
 	0, /* Use generic outmost tag fetcher */
 	asn1_DEF_BOOLEAN_tags,
 	sizeof(asn1_DEF_BOOLEAN_tags)/sizeof(asn1_DEF_BOOLEAN_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Always in primitive form */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/ENUMERATED.c b/skeletons/ENUMERATED.c
index 12350ef..9c8db29 100644
--- a/skeletons/ENUMERATED.c
+++ b/skeletons/ENUMERATED.c
@@ -20,7 +20,6 @@
 	0, /* Use generic outmost tag fetcher */
 	asn1_DEF_ENUMERATED_tags,
 	sizeof(asn1_DEF_ENUMERATED_tags)/sizeof(asn1_DEF_ENUMERATED_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Primitive */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/GeneralString.c b/skeletons/GeneralString.c
index db3b87d..feef7cc 100644
--- a/skeletons/GeneralString.c
+++ b/skeletons/GeneralString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_GeneralString_tags,
 	sizeof(asn1_DEF_GeneralString_tags)
 	  / sizeof(asn1_DEF_GeneralString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index e846502..c66c314 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -85,7 +85,6 @@
 	asn1_DEF_GeneralizedTime_tags,
 	sizeof(asn1_DEF_GeneralizedTime_tags)
 	  / sizeof(asn1_DEF_GeneralizedTime_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/GraphicString.c b/skeletons/GraphicString.c
index bd93146..f6d0ae9 100644
--- a/skeletons/GraphicString.c
+++ b/skeletons/GraphicString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_GraphicString_tags,
 	sizeof(asn1_DEF_GraphicString_tags)
 	  / sizeof(asn1_DEF_GraphicString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/IA5String.c b/skeletons/IA5String.c
index e3ae82f..33f38a6 100644
--- a/skeletons/IA5String.c
+++ b/skeletons/IA5String.c
@@ -21,7 +21,6 @@
 	asn1_DEF_IA5String_tags,
 	sizeof(asn1_DEF_IA5String_tags)
 	  / sizeof(asn1_DEF_IA5String_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/INTEGER.c b/skeletons/INTEGER.c
index 16a6b74..14e91c6 100644
--- a/skeletons/INTEGER.c
+++ b/skeletons/INTEGER.c
@@ -22,7 +22,6 @@
 	0, /* Use generic outmost tag fetcher */
 	asn1_DEF_INTEGER_tags,
 	sizeof(asn1_DEF_INTEGER_tags)/sizeof(asn1_DEF_INTEGER_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Always in primitive form */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/ISO646String.c b/skeletons/ISO646String.c
index a86d0ce..7ce5496 100644
--- a/skeletons/ISO646String.c
+++ b/skeletons/ISO646String.c
@@ -21,7 +21,6 @@
 	asn1_DEF_ISO646String_tags,
 	sizeof(asn1_DEF_ISO646String_tags)
 	  / sizeof(asn1_DEF_ISO646String_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/NULL.c b/skeletons/NULL.c
index d71d90d..42afa7e 100644
--- a/skeletons/NULL.c
+++ b/skeletons/NULL.c
@@ -21,7 +21,6 @@
 	0, /* Use generic outmost tag fetcher */
 	asn1_DEF_NULL_tags,
 	sizeof(asn1_DEF_NULL_tags)/sizeof(asn1_DEF_NULL_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Always in primitive form */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/NativeEnumerated.c b/skeletons/NativeEnumerated.c
index 139a602..9c4fd8f 100644
--- a/skeletons/NativeEnumerated.c
+++ b/skeletons/NativeEnumerated.c
@@ -27,7 +27,6 @@
 	0, /* Use generic outmost tag fetcher */
 	asn1_DEF_NativeEnumerated_tags,
 	sizeof(asn1_DEF_NativeEnumerated_tags)/sizeof(asn1_DEF_NativeEnumerated_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Always in primitive form */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/NativeInteger.c b/skeletons/NativeInteger.c
index b0cc3b7..60321cc 100644
--- a/skeletons/NativeInteger.c
+++ b/skeletons/NativeInteger.c
@@ -29,7 +29,6 @@
 	0, /* Use generic outmost tag fetcher */
 	asn1_DEF_NativeInteger_tags,
 	sizeof(asn1_DEF_NativeInteger_tags)/sizeof(asn1_DEF_NativeInteger_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Always in primitive form */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/NumericString.c b/skeletons/NumericString.c
index aba1c72..a70bb5d 100644
--- a/skeletons/NumericString.c
+++ b/skeletons/NumericString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_NumericString_tags,
 	sizeof(asn1_DEF_NumericString_tags)
 	  / sizeof(asn1_DEF_NumericString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index fe20905..a44349e 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -24,7 +24,6 @@
 	asn1_DEF_OBJECT_IDENTIFIER_tags,
 	sizeof(asn1_DEF_OBJECT_IDENTIFIER_tags)
 	    / sizeof(asn1_DEF_OBJECT_IDENTIFIER_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Always in primitive form */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 71d59d3..6589334 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -23,7 +23,6 @@
 	asn1_DEF_OCTET_STRING_tags,
 	sizeof(asn1_DEF_OCTET_STRING_tags)
 	  / sizeof(asn1_DEF_OCTET_STRING_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine (primitive and constructed) */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/ObjectDescriptor.c b/skeletons/ObjectDescriptor.c
index 3a03b97..1f82e2b 100644
--- a/skeletons/ObjectDescriptor.c
+++ b/skeletons/ObjectDescriptor.c
@@ -21,7 +21,6 @@
 	asn1_DEF_ObjectDescriptor_tags,
 	sizeof(asn1_DEF_ObjectDescriptor_tags)
 	  / sizeof(asn1_DEF_ObjectDescriptor_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c
index 22d2fbc..89cbf8d 100644
--- a/skeletons/PrintableString.c
+++ b/skeletons/PrintableString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_PrintableString_tags,
 	sizeof(asn1_DEF_PrintableString_tags)
 	  / sizeof(asn1_DEF_PrintableString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index 252cc37..f1948f8 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -24,7 +24,6 @@
 	asn1_DEF_RELATIVE_OID_tags,
 	sizeof(asn1_DEF_RELATIVE_OID_tags)
 	    / sizeof(asn1_DEF_RELATIVE_OID_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	0,	/* Always in primitive form */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/T61String.c b/skeletons/T61String.c
index 2815298..5226374 100644
--- a/skeletons/T61String.c
+++ b/skeletons/T61String.c
@@ -21,7 +21,6 @@
 	asn1_DEF_T61String_tags,
 	sizeof(asn1_DEF_T61String_tags)
 	  / sizeof(asn1_DEF_T61String_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/TeletexString.c b/skeletons/TeletexString.c
index 3c20e2f..b46caed 100644
--- a/skeletons/TeletexString.c
+++ b/skeletons/TeletexString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_TeletexString_tags,
 	sizeof(asn1_DEF_TeletexString_tags)
 	  / sizeof(asn1_DEF_TeletexString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/UTCTime.c b/skeletons/UTCTime.c
index b2ca1a6..c574e4e 100644
--- a/skeletons/UTCTime.c
+++ b/skeletons/UTCTime.c
@@ -27,7 +27,6 @@
 	asn1_DEF_UTCTime_tags,
 	sizeof(asn1_DEF_UTCTime_tags)
 	  / sizeof(asn1_DEF_UTCTime_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/UTF8String.c b/skeletons/UTF8String.c
index c96c71a..384600a 100644
--- a/skeletons/UTF8String.c
+++ b/skeletons/UTF8String.c
@@ -21,7 +21,6 @@
 	asn1_DEF_UTF8String_tags,
 	sizeof(asn1_DEF_UTF8String_tags)
 	  / sizeof(asn1_DEF_UTF8String_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c
index 628ed0c..35e7bea 100644
--- a/skeletons/UniversalString.c
+++ b/skeletons/UniversalString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_UniversalString_tags,
 	sizeof(asn1_DEF_UniversalString_tags)
 	  / sizeof(asn1_DEF_UniversalString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/VideotexString.c b/skeletons/VideotexString.c
index df21b14..772c66c 100644
--- a/skeletons/VideotexString.c
+++ b/skeletons/VideotexString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_VideotexString_tags,
 	sizeof(asn1_DEF_VideotexString_tags)
 	  / sizeof(asn1_DEF_VideotexString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/VisibleString.c b/skeletons/VisibleString.c
index d1a11db..18a27fa 100644
--- a/skeletons/VisibleString.c
+++ b/skeletons/VisibleString.c
@@ -21,7 +21,6 @@
 	asn1_DEF_VisibleString_tags,
 	sizeof(asn1_DEF_VisibleString_tags)
 	  / sizeof(asn1_DEF_VisibleString_tags[0]),
-	1,	/* Single UNIVERSAL tag may be implicitly overriden */
 	-1,	/* Both ways are fine */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/skeletons/ber_decoder.c b/skeletons/ber_decoder.c
index b2c08f5..24a47ac 100644
--- a/skeletons/ber_decoder.c
+++ b/skeletons/ber_decoder.c
@@ -53,7 +53,7 @@
 	int tagno;
 
 	/*
-	 * So what does all this tags_impl_skip stuff mean?
+	 * So what does all this implicit skip stuff mean?
 	 * Imagine two types,
 	 * 	A ::= [5] IMPLICIT	T
 	 * 	B ::= [2] EXPLICIT	T
@@ -74,30 +74,14 @@
 	 * it appropriately.
 	 */
 
-	/*
-	 * We have a list of tags that must occur in the stream:
-	 * 	{A,B,C}
-	 * However, it may be indicated that the type is
-	 * implicitly tagged in the caller, so it really boils down to the
-	 *	{I,B,C} or even {I,C}
-	 * This is because the implicit tag at above structure may replace 
-	 * zero or more (or every) tags which follow it. We don't care
-	 * about the precise number, as it is already computed for us
-	 * by the ASN.1 compiler and placed into td->tags_impl_skip.
-	 * So let's suppose the only tag left after implicit tagging is {I}.
-	 * Yet, the table we have is {A,B,C} and td->tags_impl_skip=3.
-	 * We need to check at least one tag in the loop, so the loop range
-	 * is modified so it will be invoked at least one time.
-	 */
 	tagno = ctx->step	/* Continuing where left previously */
-		+ (tag_mode==-1?(td->tags_impl_skip-1):0)
 		+ (tag_mode==1?-1:0)
 		;
 	ASN_DEBUG("ber_check_tags(%s, size=%ld, tm=%d, step=%d, tagno=%d)",
 		td->name, (long)size, tag_mode, ctx->step, tagno);
 	//assert(td->tags_count >= 1); ?May not be the case for CHOICE or ANY.
 
-	if(tagno == td->tags_count) {
+	if(tag_mode == 0 && tagno == td->tags_count) {
 		/*
 		 * This must be the _untagged_ ANY type,
 		 * which outermost tag isn't known in advance.
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 649f53b..36412a6 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -226,8 +226,10 @@
 		 * Fetch the T from TLV.
 		 */
 		tag_len = ber_fetch_tag(ptr, LEFT, &tlv_tag);
-		ASN_DEBUG("In %s SEQUENCE for %d %s next tag length %d",
-			td->name, edx, elements[edx].name, (int)tag_len);
+		ASN_DEBUG("Current tag in %s SEQUENCE for element %d "
+			"(%s) is %s encoded in %d bytes, left %ld",
+			td->name, edx, elements[edx].name,
+			ber_tlv_tag_string(tlv_tag), (int)tag_len, (long)LEFT);
 		switch(tag_len) {
 		case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
 			/* Fall through */
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c
index f103fa3..7a31334 100644
--- a/skeletons/constr_SET.c
+++ b/skeletons/constr_SET.c
@@ -654,7 +654,6 @@
 int
 SET_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
 		asn_app_consume_bytes_f *app_errlog, void *app_key) {
-	asn1_SET_specifics_t *specs = (asn1_SET_specifics_t *)td->specifics;
 	int edx;
 
 	if(!sptr) {
diff --git a/skeletons/constr_TYPE.h b/skeletons/constr_TYPE.h
index e072ec5..1918b5c 100644
--- a/skeletons/constr_TYPE.h
+++ b/skeletons/constr_TYPE.h
@@ -74,7 +74,6 @@
 	 */
 	ber_tlv_tag_t *tags;	/* At least one tag must be specified */
 	int tags_count;		/* Number of tags which are expected */
-	int tags_impl_skip;	/* Tags to skip in implicit mode */
 	int last_tag_form;	/* Acceptable form of the tag (prim, constr) */
 
 	/*
diff --git a/skeletons/constraints.c b/skeletons/constraints.c
index a7dce95..862d8f1 100644
--- a/skeletons/constraints.c
+++ b/skeletons/constraints.c
@@ -112,12 +112,13 @@
 
 	
 	va_start(ap, fmt);
-	ret = vsnprintf(buf, len, fmt, ap);
+	ret = vsnprintf(p, len, fmt, ap);
 	va_end(ap);
 	if(ret < 0 || ret >= (ssize_t)len) {
 		ret = sizeof("<broken vsnprintf>") - 1;
 		memcpy(buf, "<broken vsnprintf>", ret + 1);
+		p = buf;
 	}
 
-	cb(buf, ret, key);
+	cb(p, ret, key);
 }
diff --git a/skeletons/der_encoder.c b/skeletons/der_encoder.c
index fbdccec..be71492 100644
--- a/skeletons/der_encoder.c
+++ b/skeletons/der_encoder.c
@@ -44,12 +44,12 @@
 	ssize_t *lens;
 	int i;
 
-	ASN_DEBUG("Writing tags (%s, tm=%d, tc=%d, iskip=%d, tag=%s, mtc=%d)",
-		sd->name, tag_mode, sd->tags_count, sd->tags_impl_skip,
+	ASN_DEBUG("Writing tags (%s, tm=%d, tc=%d, tag=%s, mtc=%d)",
+		sd->name, tag_mode, sd->tags_count,
 		ber_tlv_tag_string(tag),
 		tag_mode
 			?(sd->tags_count+1
-				-((tag_mode==-1)?sd->tags_impl_skip:0))
+				-((tag_mode == -1) && sd->tags_count))
 			:sd->tags_count
 	);
 
@@ -67,10 +67,10 @@
 		}
 		tags_count = sd->tags_count
 			+ 1	/* EXPLICIT or IMPLICIT tag is given */
-			- ((tag_mode==-1)?sd->tags_impl_skip:0);
+			- ((tag_mode == -1) && sd->tags_count);
 		/* Copy tags over */
 		tags[0] = tag;
-		stag_offset = -1 + ((tag_mode==-1)?sd->tags_impl_skip:0);
+		stag_offset = -1 + ((tag_mode == -1) && sd->tags_count);
 		for(i = 1; i < tags_count; i++)
 			tags[i] = sd->tags[i + stag_offset];
 	} else {
diff --git a/tests/19-param-OK.asn1.-P b/tests/19-param-OK.asn1.-P
index ec393c0..bed6a5f 100644
--- a/tests/19-param-OK.asn1.-P
+++ b/tests/19-param-OK.asn1.-P
@@ -117,7 +117,6 @@
 	asn1_DEF_toBeSigned_tags,
 	sizeof(asn1_DEF_toBeSigned_tags)
 		/sizeof(asn1_DEF_toBeSigned_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_toBeSigned,
 	3,	/* Elements count */
@@ -174,7 +173,6 @@
 	asn1_DEF_Certificate_tags,
 	sizeof(asn1_DEF_Certificate_tags)
 		/sizeof(asn1_DEF_Certificate_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_Certificate,
 	3,	/* Elements count */
@@ -231,7 +229,6 @@
 	asn1_DEF_Name_tags,
 	sizeof(asn1_DEF_Name_tags)
 		/sizeof(asn1_DEF_Name_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_Name,
 	1,	/* Single element */
@@ -343,7 +340,6 @@
 	asn1_DEF_RelativeDistinguishedName_tags,
 	sizeof(asn1_DEF_RelativeDistinguishedName_tags)
 		/sizeof(asn1_DEF_RelativeDistinguishedName_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_RelativeDistinguishedName,
 	1,	/* Single element */
diff --git a/tests/31-set-of-OK.asn1.-P b/tests/31-set-of-OK.asn1.-P
index b3c6ce6..e28455a 100644
--- a/tests/31-set-of-OK.asn1.-P
+++ b/tests/31-set-of-OK.asn1.-P
@@ -48,7 +48,6 @@
 	asn1_DEF_Forest_tags,
 	sizeof(asn1_DEF_Forest_tags)
 		/sizeof(asn1_DEF_Forest_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_Forest,
 	1,	/* Single element */
@@ -120,7 +119,6 @@
 	asn1_DEF_Tree_tags,
 	sizeof(asn1_DEF_Tree_tags)
 		/sizeof(asn1_DEF_Tree_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_Tree,
 	2,	/* Elements count */
@@ -213,7 +211,6 @@
 	asn1_DEF_trees_tags,
 	sizeof(asn1_DEF_trees_tags)
 		/sizeof(asn1_DEF_trees_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_trees,
 	1,	/* Single element */
@@ -255,7 +252,6 @@
 	asn1_DEF_anything_member_tags,
 	sizeof(asn1_DEF_anything_member_tags)
 		/sizeof(asn1_DEF_anything_member_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_anything_member,
 	1,	/* Elements count */
@@ -290,7 +286,6 @@
 	asn1_DEF_anything_tags,
 	sizeof(asn1_DEF_anything_tags)
 		/sizeof(asn1_DEF_anything_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_anything,
 	1,	/* Single element */
@@ -343,7 +338,6 @@
 	asn1_DEF_Stuff_tags,
 	sizeof(asn1_DEF_Stuff_tags)
 		/sizeof(asn1_DEF_Stuff_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_Stuff,
 	2,	/* Elements count */
diff --git a/tests/39-sequence-of-OK.asn1.-P b/tests/39-sequence-of-OK.asn1.-P
index 2b8df8b..a1f622b 100644
--- a/tests/39-sequence-of-OK.asn1.-P
+++ b/tests/39-sequence-of-OK.asn1.-P
@@ -57,7 +57,6 @@
 	asn1_DEF_collection_tags,
 	sizeof(asn1_DEF_collection_tags)
 		/sizeof(asn1_DEF_collection_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_collection,
 	1,	/* Single element */
@@ -106,7 +105,6 @@
 	asn1_DEF_T_tags,
 	sizeof(asn1_DEF_T_tags)
 		/sizeof(asn1_DEF_T_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T,
 	2,	/* Elements count */
@@ -179,7 +177,6 @@
 	asn1_DEF_T2_tags,
 	sizeof(asn1_DEF_T2_tags)
 		/sizeof(asn1_DEF_T2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T2,
 	2,	/* Elements count */
diff --git a/tests/42-real-life-OK.asn1.-PR b/tests/42-real-life-OK.asn1.-PR
index 4cdd039..385dcb9 100644
--- a/tests/42-real-life-OK.asn1.-PR
+++ b/tests/42-real-life-OK.asn1.-PR
@@ -93,7 +93,6 @@
 	asn1_DEF_varsets_tags,
 	sizeof(asn1_DEF_varsets_tags)
 		/sizeof(asn1_DEF_varsets_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_varsets,
 	1,	/* Single element */
@@ -142,7 +141,6 @@
 	asn1_DEF_LogLine_tags,
 	sizeof(asn1_DEF_LogLine_tags)
 		/sizeof(asn1_DEF_LogLine_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_LogLine,
 	2,	/* Elements count */
@@ -235,7 +233,6 @@
 	asn1_DEF_vparts_tags,
 	sizeof(asn1_DEF_vparts_tags)
 		/sizeof(asn1_DEF_vparts_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_vparts,
 	1,	/* Single element */
@@ -284,7 +281,6 @@
 	asn1_DEF_VariablePartSet_tags,
 	sizeof(asn1_DEF_VariablePartSet_tags)
 		/sizeof(asn1_DEF_VariablePartSet_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_VariablePartSet,
 	2,	/* Elements count */
@@ -405,7 +401,6 @@
 	asn1_DEF_vset_tags,
 	sizeof(asn1_DEF_vset_tags)
 		/sizeof(asn1_DEF_vset_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_vset,
 	1,	/* Single element */
@@ -455,7 +450,6 @@
 	asn1_DEF_vrange_tags,
 	sizeof(asn1_DEF_vrange_tags)
 		/sizeof(asn1_DEF_vrange_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_vrange,
 	2,	/* Elements count */
@@ -501,7 +495,6 @@
 	CHOICE_outmost_tag,
 	0,	/* No explicit tags (pointer) */
 	0,	/* No explicit tags (count) */
-	0,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_VariablePart,
 	2,	/* Elements count */
@@ -590,7 +583,6 @@
 	asn1_DEF_email_tags,
 	sizeof(asn1_DEF_email_tags)
 		/sizeof(asn1_DEF_email_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_email,
 	1,	/* Single element */
@@ -640,7 +632,6 @@
 	asn1_DEF_notify_tags,
 	sizeof(asn1_DEF_notify_tags)
 		/sizeof(asn1_DEF_notify_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_notify,
 	2,	/* Elements count */
@@ -689,7 +680,6 @@
 	asn1_DEF_ActionItem_tags,
 	sizeof(asn1_DEF_ActionItem_tags)
 		/sizeof(asn1_DEF_ActionItem_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_ActionItem,
 	2,	/* Elements count */
diff --git a/tests/43-recursion-OK.asn1.-P b/tests/43-recursion-OK.asn1.-P
index c89e881..18c02d7 100644
--- a/tests/43-recursion-OK.asn1.-P
+++ b/tests/43-recursion-OK.asn1.-P
@@ -66,7 +66,6 @@
 	asn1_DEF_t_member1_tags,
 	sizeof(asn1_DEF_t_member1_tags)
 		/sizeof(asn1_DEF_t_member1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_t_member1,
 	1,	/* Single element */
@@ -101,7 +100,6 @@
 	asn1_DEF_t_member2_tags,
 	sizeof(asn1_DEF_t_member2_tags)
 		/sizeof(asn1_DEF_t_member2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_t_member2,
 	1,	/* Single element */
@@ -166,7 +164,6 @@
 	asn1_DEF_Test_structure_1_tags,
 	sizeof(asn1_DEF_Test_structure_1_tags)
 		/sizeof(asn1_DEF_Test_structure_1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_Test_structure_1,
 	4,	/* Elements count */
@@ -244,7 +241,6 @@
 	asn1_DEF_or_tags,
 	sizeof(asn1_DEF_or_tags)
 		/sizeof(asn1_DEF_or_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_or,
 	1,	/* Single element */
@@ -306,7 +302,6 @@
 	CHOICE_outmost_tag,
 	0,	/* No explicit tags (pointer) */
 	0,	/* No explicit tags (count) */
-	0,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_Choice_1,
 	4,	/* Elements count */
diff --git a/tests/44-choice-in-sequence-OK.asn1.-P b/tests/44-choice-in-sequence-OK.asn1.-P
index 413ff00..107cdb8 100644
--- a/tests/44-choice-in-sequence-OK.asn1.-P
+++ b/tests/44-choice-in-sequence-OK.asn1.-P
@@ -108,7 +108,6 @@
 	CHOICE_outmost_tag,
 	0,	/* No explicit tags (pointer) */
 	0,	/* No explicit tags (count) */
-	0,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_e,
 	2,	/* Elements count */
@@ -155,7 +154,6 @@
 	CHOICE_outmost_tag,
 	0,	/* No explicit tags (pointer) */
 	0,	/* No explicit tags (count) */
-	0,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_h,
 	2,	/* Elements count */
@@ -219,7 +217,6 @@
 	CHOICE_outmost_tag,
 	0,	/* No explicit tags (pointer) */
 	0,	/* No explicit tags (count) */
-	0,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_b,
 	4,	/* Elements count */
@@ -272,7 +269,6 @@
 	asn1_DEF_T_tags,
 	sizeof(asn1_DEF_T_tags)
 		/sizeof(asn1_DEF_T_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T,
 	2,	/* Elements count */
diff --git a/tests/46-redefine-OK.asn1.-PR b/tests/46-redefine-OK.asn1.-PR
index c78b29f..ea256a8 100644
--- a/tests/46-redefine-OK.asn1.-PR
+++ b/tests/46-redefine-OK.asn1.-PR
@@ -49,8 +49,7 @@
 PrimitiveType_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	PrimitiveType_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -92,7 +91,6 @@
 	asn1_DEF_PrimitiveType_tags,
 	sizeof(asn1_DEF_PrimitiveType_tags)
 		/sizeof(asn1_DEF_PrimitiveType_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -154,7 +152,6 @@
 	asn1_DEF_ConstructedType_tags,
 	sizeof(asn1_DEF_ConstructedType_tags)
 		/sizeof(asn1_DEF_ConstructedType_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_ConstructedType,
 	1,	/* Elements count */
@@ -212,8 +209,7 @@
 T_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	T_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -255,7 +251,6 @@
 	asn1_DEF_T_tags,
 	sizeof(asn1_DEF_T_tags)
 		/sizeof(asn1_DEF_T_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* Defined elsewhere */
 	0	/* No specifics */
diff --git a/tests/47-set-ext-OK.asn1.-P b/tests/47-set-ext-OK.asn1.-P
index 8354a16..5a3e2c1 100644
--- a/tests/47-set-ext-OK.asn1.-P
+++ b/tests/47-set-ext-OK.asn1.-P
@@ -73,7 +73,6 @@
 	asn1_DEF_T1_tags,
 	sizeof(asn1_DEF_T1_tags)
 		/sizeof(asn1_DEF_T1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T1,
 	1,	/* Elements count */
@@ -155,7 +154,6 @@
 	asn1_DEF_T2_tags,
 	sizeof(asn1_DEF_T2_tags)
 		/sizeof(asn1_DEF_T2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T2,
 	1,	/* Elements count */
@@ -227,7 +225,6 @@
 	CHOICE_outmost_tag,
 	0,	/* No explicit tags (pointer) */
 	0,	/* No explicit tags (count) */
-	0,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T3,
 	1,	/* Elements count */
@@ -299,7 +296,6 @@
 	CHOICE_outmost_tag,
 	0,	/* No explicit tags (pointer) */
 	0,	/* No explicit tags (count) */
-	0,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T4,
 	1,	/* Elements count */
diff --git a/tests/50-constraint-OK.asn1.-P b/tests/50-constraint-OK.asn1.-P
index 3ae2200..4459f53 100644
--- a/tests/50-constraint-OK.asn1.-P
+++ b/tests/50-constraint-OK.asn1.-P
@@ -49,8 +49,7 @@
 Int1_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int1_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -92,7 +91,6 @@
 	asn1_DEF_Int1_tags,
 	sizeof(asn1_DEF_Int1_tags)
 		/sizeof(asn1_DEF_Int1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -167,8 +165,7 @@
 Int2_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int2_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -197,7 +194,7 @@
 /*** <<< STAT-DEFS [Int2] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Int2_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Int2 = {
 	"Int2",
@@ -210,7 +207,6 @@
 	asn1_DEF_Int2_tags,
 	sizeof(asn1_DEF_Int2_tags)
 		/sizeof(asn1_DEF_Int2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -289,8 +285,7 @@
 Int3_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int3_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -319,7 +314,7 @@
 /*** <<< STAT-DEFS [Int3] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Int3_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Int3 = {
 	"Int3",
@@ -332,7 +327,6 @@
 	asn1_DEF_Int3_tags,
 	sizeof(asn1_DEF_Int3_tags)
 		/sizeof(asn1_DEF_Int3_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -411,8 +405,7 @@
 Int4_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int4_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -441,7 +434,7 @@
 /*** <<< STAT-DEFS [Int4] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Int4_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Int4 = {
 	"Int4",
@@ -454,7 +447,6 @@
 	asn1_DEF_Int4_tags,
 	sizeof(asn1_DEF_Int4_tags)
 		/sizeof(asn1_DEF_Int4_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -533,8 +525,7 @@
 Int5_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Int5_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -563,7 +554,7 @@
 /*** <<< STAT-DEFS [Int5] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Int5_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Int5 = {
 	"Int5",
@@ -576,7 +567,6 @@
 	asn1_DEF_Int5_tags,
 	sizeof(asn1_DEF_Int5_tags)
 		/sizeof(asn1_DEF_Int5_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -655,8 +645,7 @@
 ExtensibleExtensions_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	ExtensibleExtensions_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -698,7 +687,6 @@
 	asn1_DEF_ExtensibleExtensions_tags,
 	sizeof(asn1_DEF_ExtensibleExtensions_tags)
 		/sizeof(asn1_DEF_ExtensibleExtensions_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -755,8 +743,7 @@
 Str1_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Str1_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -798,7 +785,6 @@
 	asn1_DEF_Str1_tags,
 	sizeof(asn1_DEF_Str1_tags)
 		/sizeof(asn1_DEF_Str1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -889,8 +875,7 @@
 Str2_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Str2_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -919,7 +904,7 @@
 /*** <<< STAT-DEFS [Str2] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Str2_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Str2 = {
 	"Str2",
@@ -932,7 +917,6 @@
 	asn1_DEF_Str2_tags,
 	sizeof(asn1_DEF_Str2_tags)
 		/sizeof(asn1_DEF_Str2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1034,8 +1018,7 @@
 Str3_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Str3_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1064,7 +1047,7 @@
 /*** <<< STAT-DEFS [Str3] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Str3_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Str3 = {
 	"Str3",
@@ -1077,7 +1060,6 @@
 	asn1_DEF_Str3_tags,
 	sizeof(asn1_DEF_Str3_tags)
 		/sizeof(asn1_DEF_Str3_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1165,8 +1147,7 @@
 Str4_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Str4_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1208,7 +1189,6 @@
 	asn1_DEF_Str4_tags,
 	sizeof(asn1_DEF_Str4_tags)
 		/sizeof(asn1_DEF_Str4_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1296,8 +1276,7 @@
 PER_Visible_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	PER_Visible_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1339,7 +1318,6 @@
 	asn1_DEF_PER_Visible_tags,
 	sizeof(asn1_DEF_PER_Visible_tags)
 		/sizeof(asn1_DEF_PER_Visible_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1427,8 +1405,7 @@
 PER_Visible_2_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	PER_Visible_2_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1457,7 +1434,7 @@
 /*** <<< STAT-DEFS [PER-Visible-2] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_PER_Visible_2_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_PER_Visible_2 = {
 	"PER-Visible-2",
@@ -1470,7 +1447,6 @@
 	asn1_DEF_PER_Visible_2_tags,
 	sizeof(asn1_DEF_PER_Visible_2_tags)
 		/sizeof(asn1_DEF_PER_Visible_2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1558,8 +1534,7 @@
 Not_PER_Visible_1_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Not_PER_Visible_1_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1588,7 +1563,7 @@
 /*** <<< STAT-DEFS [Not-PER-Visible-1] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Not_PER_Visible_1_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Not_PER_Visible_1 = {
 	"Not-PER-Visible-1",
@@ -1601,7 +1576,6 @@
 	asn1_DEF_Not_PER_Visible_1_tags,
 	sizeof(asn1_DEF_Not_PER_Visible_1_tags)
 		/sizeof(asn1_DEF_Not_PER_Visible_1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1689,8 +1663,7 @@
 Not_PER_Visible_2_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Not_PER_Visible_2_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1719,7 +1692,7 @@
 /*** <<< STAT-DEFS [Not-PER-Visible-2] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Not_PER_Visible_2_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Not_PER_Visible_2 = {
 	"Not-PER-Visible-2",
@@ -1732,7 +1705,6 @@
 	asn1_DEF_Not_PER_Visible_2_tags,
 	sizeof(asn1_DEF_Not_PER_Visible_2_tags)
 		/sizeof(asn1_DEF_Not_PER_Visible_2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1820,8 +1792,7 @@
 Not_PER_Visible_3_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Not_PER_Visible_3_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1850,7 +1821,7 @@
 /*** <<< STAT-DEFS [Not-PER-Visible-3] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Not_PER_Visible_3_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Not_PER_Visible_3 = {
 	"Not-PER-Visible-3",
@@ -1863,7 +1834,6 @@
 	asn1_DEF_Not_PER_Visible_3_tags,
 	sizeof(asn1_DEF_Not_PER_Visible_3_tags)
 		/sizeof(asn1_DEF_Not_PER_Visible_3_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -1954,8 +1924,7 @@
 SIZE_but_not_FROM_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	SIZE_but_not_FROM_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -1984,7 +1953,7 @@
 /*** <<< STAT-DEFS [SIZE-but-not-FROM] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_SIZE_but_not_FROM_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_SIZE_but_not_FROM = {
 	"SIZE-but-not-FROM",
@@ -1997,7 +1966,6 @@
 	asn1_DEF_SIZE_but_not_FROM_tags,
 	sizeof(asn1_DEF_SIZE_but_not_FROM_tags)
 		/sizeof(asn1_DEF_SIZE_but_not_FROM_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -2088,8 +2056,7 @@
 SIZE_and_FROM_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	SIZE_and_FROM_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -2118,7 +2085,7 @@
 /*** <<< STAT-DEFS [SIZE-and-FROM] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_SIZE_and_FROM_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_SIZE_and_FROM = {
 	"SIZE-and-FROM",
@@ -2131,7 +2098,6 @@
 	asn1_DEF_SIZE_and_FROM_tags,
 	sizeof(asn1_DEF_SIZE_and_FROM_tags)
 		/sizeof(asn1_DEF_SIZE_and_FROM_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -2219,8 +2185,7 @@
 Neither_SIZE_nor_FROM_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Neither_SIZE_nor_FROM_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -2249,7 +2214,7 @@
 /*** <<< STAT-DEFS [Neither-SIZE-nor-FROM] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Neither_SIZE_nor_FROM_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (22 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Neither_SIZE_nor_FROM = {
 	"Neither-SIZE-nor-FROM",
@@ -2262,7 +2227,6 @@
 	asn1_DEF_Neither_SIZE_nor_FROM_tags,
 	sizeof(asn1_DEF_Neither_SIZE_nor_FROM_tags)
 		/sizeof(asn1_DEF_Neither_SIZE_nor_FROM_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -2367,8 +2331,7 @@
 Utf8_3_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Utf8_3_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -2397,7 +2360,7 @@
 /*** <<< STAT-DEFS [Utf8-3] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Utf8_3_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Utf8_3 = {
 	"Utf8-3",
@@ -2410,7 +2373,6 @@
 	asn1_DEF_Utf8_3_tags,
 	sizeof(asn1_DEF_Utf8_3_tags)
 		/sizeof(asn1_DEF_Utf8_3_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -2485,8 +2447,7 @@
 Utf8_2_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Utf8_2_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -2515,7 +2476,7 @@
 /*** <<< STAT-DEFS [Utf8-2] >>> ***/
 
 static ber_tlv_tag_t asn1_DEF_Utf8_2_tags[] = {
-	(ASN_TAG_CLASS_UNIVERSAL | (0 << 2))
+	(ASN_TAG_CLASS_UNIVERSAL | (12 << 2))
 };
 asn1_TYPE_descriptor_t asn1_DEF_Utf8_2 = {
 	"Utf8-2",
@@ -2528,7 +2489,6 @@
 	asn1_DEF_Utf8_2_tags,
 	sizeof(asn1_DEF_Utf8_2_tags)
 		/sizeof(asn1_DEF_Utf8_2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
@@ -2585,8 +2545,7 @@
 Utf8_1_decode_ber(asn1_TYPE_descriptor_t *td,
 		void **structure, void *bufptr, size_t size, int tag_mode) {
 	Utf8_1_inherit_TYPE_descriptor(td);
-	return td->ber_decoder(td, structure,
-		bufptr, size, tag_mode);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
 }
 
 der_enc_rval_t
@@ -2628,7 +2587,6 @@
 	asn1_DEF_Utf8_1_tags,
 	sizeof(asn1_DEF_Utf8_1_tags)
 		/sizeof(asn1_DEF_Utf8_1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	-0,	/* Unknown yet */
 	0, 0,	/* No members */
 	0	/* No specifics */
diff --git a/tests/60-any-OK.asn1.-P b/tests/60-any-OK.asn1.-P
index 96098a5..86d47f4 100644
--- a/tests/60-any-OK.asn1.-P
+++ b/tests/60-any-OK.asn1.-P
@@ -63,7 +63,6 @@
 	asn1_DEF_T1_tags,
 	sizeof(asn1_DEF_T1_tags)
 		/sizeof(asn1_DEF_T1_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T1,
 	2,	/* Elements count */
@@ -136,7 +135,6 @@
 	asn1_DEF_T2_tags,
 	sizeof(asn1_DEF_T2_tags)
 		/sizeof(asn1_DEF_T2_tags[0]), /* 1 */
-	1,	/* Tags to skip */
 	1,	/* Whether CONSTRUCTED */
 	asn1_MBR_T2,
 	2,	/* Elements count */
diff --git a/tests/65-multi-tag-OK.asn1 b/tests/65-multi-tag-OK.asn1
new file mode 100644
index 0000000..32e85cc
--- /dev/null
+++ b/tests/65-multi-tag-OK.asn1
@@ -0,0 +1,29 @@
+
+-- OK: Everything is fine
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .65
+
+ModuleTestMultipleTags
+	{ iso org(3) dod(6) internet(1) private(4) enterprise(1)
+		spelio(9363) software(1) asn1c(5) test(1) 65 }
+	DEFINITIONS ::=
+BEGIN
+
+	T1 ::= [2] EXPLICIT T2
+	T2 ::= [3] EXPLICIT T3
+	T3 ::= [4] IMPLICIT T4
+	T4 ::= [5] EXPLICIT T5
+	T5 ::= [6] IMPLICIT T6
+	T6 ::= INTEGER
+
+	T ::= [0] IMPLICIT Ts
+
+	Ts ::= [123] IMPLICIT SEQUENCE {
+		m1	[1] IMPLICIT T2,	-- [1][4][6]
+		m2	[2] EXPLICIT T3 OPTIONAL, -- [2][4][6]
+		m3	[3] IMPLICIT T3 	-- [3][6]
+	}
+
+END
diff --git a/tests/65-multi-tag-OK.asn1.-P b/tests/65-multi-tag-OK.asn1.-P
new file mode 100644
index 0000000..fec7c9c
--- /dev/null
+++ b/tests/65-multi-tag-OK.asn1.-P
@@ -0,0 +1,774 @@
+
+/*** <<< INCLUDES [T1] >>> ***/
+
+#include <T2.h>
+
+/*** <<< TYPE-DECLS [T1] >>> ***/
+
+
+typedef T2_t	 T1_t;
+
+/*** <<< FUNC-DECLS [T1] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_T1;
+asn_constr_check_f T1_constraint;
+ber_type_decoder_f T1_decode_ber;
+der_type_encoder_f T1_encode_der;
+asn_struct_print_f T1_print;
+asn_struct_free_f T1_free;
+
+/*** <<< CODE [T1] >>> ***/
+
+int
+T1_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_consume_bytes_f *app_errlog, void *app_key) {
+	
+	/* Make the underlying type checker permanent */
+	td->check_constraints = asn1_DEF_T2.check_constraints;
+	return td->check_constraints
+		(td, sptr, app_errlog, app_key);
+}
+
+/*
+ * This type is implemented using T2,
+ * so adjust the DEF appropriately.
+ */
+static void
+T1_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {
+	td->ber_decoder    = asn1_DEF_T2.ber_decoder;
+	td->der_encoder    = asn1_DEF_T2.der_encoder;
+	td->free_struct    = asn1_DEF_T2.free_struct;
+	td->print_struct   = asn1_DEF_T2.print_struct;
+	td->last_tag_form  = asn1_DEF_T2.last_tag_form;
+	td->elements       = asn1_DEF_T2.elements;
+	td->elements_count = asn1_DEF_T2.elements_count;
+	td->specifics      = asn1_DEF_T2.specifics;
+}
+
+ber_dec_rval_t
+T1_decode_ber(asn1_TYPE_descriptor_t *td,
+		void **structure, void *bufptr, size_t size, int tag_mode) {
+	T1_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
+}
+
+der_enc_rval_t
+T1_encode_der(asn1_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	T1_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+int
+T1_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	T1_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+void
+T1_free(asn1_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	T1_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+
+/*** <<< STAT-DEFS [T1] >>> ***/
+
+static ber_tlv_tag_t asn1_DEF_T1_tags[] = {
+	(ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+	(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+	(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
+	(ASN_TAG_CLASS_CONTEXT | (6 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_T1 = {
+	"T1",
+	T1_constraint,
+	T1_decode_ber,
+	T1_encode_der,
+	T1_print,
+	T1_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_T1_tags,
+	sizeof(asn1_DEF_T1_tags)
+		/sizeof(asn1_DEF_T1_tags[0]), /* 4 */
+	-0,	/* Unknown yet */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+
+/*** <<< INCLUDES [T2] >>> ***/
+
+#include <T3.h>
+
+/*** <<< TYPE-DECLS [T2] >>> ***/
+
+
+typedef T3_t	 T2_t;
+
+/*** <<< FUNC-DECLS [T2] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_T2;
+asn_constr_check_f T2_constraint;
+ber_type_decoder_f T2_decode_ber;
+der_type_encoder_f T2_encode_der;
+asn_struct_print_f T2_print;
+asn_struct_free_f T2_free;
+
+/*** <<< CODE [T2] >>> ***/
+
+int
+T2_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_consume_bytes_f *app_errlog, void *app_key) {
+	
+	/* Make the underlying type checker permanent */
+	td->check_constraints = asn1_DEF_T3.check_constraints;
+	return td->check_constraints
+		(td, sptr, app_errlog, app_key);
+}
+
+/*
+ * This type is implemented using T3,
+ * so adjust the DEF appropriately.
+ */
+static void
+T2_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {
+	td->ber_decoder    = asn1_DEF_T3.ber_decoder;
+	td->der_encoder    = asn1_DEF_T3.der_encoder;
+	td->free_struct    = asn1_DEF_T3.free_struct;
+	td->print_struct   = asn1_DEF_T3.print_struct;
+	td->last_tag_form  = asn1_DEF_T3.last_tag_form;
+	td->elements       = asn1_DEF_T3.elements;
+	td->elements_count = asn1_DEF_T3.elements_count;
+	td->specifics      = asn1_DEF_T3.specifics;
+}
+
+ber_dec_rval_t
+T2_decode_ber(asn1_TYPE_descriptor_t *td,
+		void **structure, void *bufptr, size_t size, int tag_mode) {
+	T2_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
+}
+
+der_enc_rval_t
+T2_encode_der(asn1_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	T2_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+int
+T2_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	T2_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+void
+T2_free(asn1_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	T2_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+
+/*** <<< STAT-DEFS [T2] >>> ***/
+
+static ber_tlv_tag_t asn1_DEF_T2_tags[] = {
+	(ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+	(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
+	(ASN_TAG_CLASS_CONTEXT | (6 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_T2 = {
+	"T2",
+	T2_constraint,
+	T2_decode_ber,
+	T2_encode_der,
+	T2_print,
+	T2_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_T2_tags,
+	sizeof(asn1_DEF_T2_tags)
+		/sizeof(asn1_DEF_T2_tags[0]), /* 3 */
+	-0,	/* Unknown yet */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+
+/*** <<< INCLUDES [T3] >>> ***/
+
+#include <T4.h>
+
+/*** <<< TYPE-DECLS [T3] >>> ***/
+
+
+typedef T4_t	 T3_t;
+
+/*** <<< FUNC-DECLS [T3] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_T3;
+asn_constr_check_f T3_constraint;
+ber_type_decoder_f T3_decode_ber;
+der_type_encoder_f T3_encode_der;
+asn_struct_print_f T3_print;
+asn_struct_free_f T3_free;
+
+/*** <<< CODE [T3] >>> ***/
+
+int
+T3_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_consume_bytes_f *app_errlog, void *app_key) {
+	
+	/* Make the underlying type checker permanent */
+	td->check_constraints = asn1_DEF_T4.check_constraints;
+	return td->check_constraints
+		(td, sptr, app_errlog, app_key);
+}
+
+/*
+ * This type is implemented using T4,
+ * so adjust the DEF appropriately.
+ */
+static void
+T3_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {
+	td->ber_decoder    = asn1_DEF_T4.ber_decoder;
+	td->der_encoder    = asn1_DEF_T4.der_encoder;
+	td->free_struct    = asn1_DEF_T4.free_struct;
+	td->print_struct   = asn1_DEF_T4.print_struct;
+	td->last_tag_form  = asn1_DEF_T4.last_tag_form;
+	td->elements       = asn1_DEF_T4.elements;
+	td->elements_count = asn1_DEF_T4.elements_count;
+	td->specifics      = asn1_DEF_T4.specifics;
+}
+
+ber_dec_rval_t
+T3_decode_ber(asn1_TYPE_descriptor_t *td,
+		void **structure, void *bufptr, size_t size, int tag_mode) {
+	T3_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
+}
+
+der_enc_rval_t
+T3_encode_der(asn1_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	T3_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+int
+T3_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	T3_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+void
+T3_free(asn1_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	T3_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+
+/*** <<< STAT-DEFS [T3] >>> ***/
+
+static ber_tlv_tag_t asn1_DEF_T3_tags[] = {
+	(ASN_TAG_CLASS_CONTEXT | (4 << 2)),
+	(ASN_TAG_CLASS_CONTEXT | (6 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_T3 = {
+	"T3",
+	T3_constraint,
+	T3_decode_ber,
+	T3_encode_der,
+	T3_print,
+	T3_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_T3_tags,
+	sizeof(asn1_DEF_T3_tags)
+		/sizeof(asn1_DEF_T3_tags[0]), /* 2 */
+	-0,	/* Unknown yet */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+
+/*** <<< INCLUDES [T4] >>> ***/
+
+#include <T5.h>
+
+/*** <<< TYPE-DECLS [T4] >>> ***/
+
+
+typedef T5_t	 T4_t;
+
+/*** <<< FUNC-DECLS [T4] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_T4;
+asn_constr_check_f T4_constraint;
+ber_type_decoder_f T4_decode_ber;
+der_type_encoder_f T4_encode_der;
+asn_struct_print_f T4_print;
+asn_struct_free_f T4_free;
+
+/*** <<< CODE [T4] >>> ***/
+
+int
+T4_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_consume_bytes_f *app_errlog, void *app_key) {
+	
+	/* Make the underlying type checker permanent */
+	td->check_constraints = asn1_DEF_T5.check_constraints;
+	return td->check_constraints
+		(td, sptr, app_errlog, app_key);
+}
+
+/*
+ * This type is implemented using T5,
+ * so adjust the DEF appropriately.
+ */
+static void
+T4_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {
+	td->ber_decoder    = asn1_DEF_T5.ber_decoder;
+	td->der_encoder    = asn1_DEF_T5.der_encoder;
+	td->free_struct    = asn1_DEF_T5.free_struct;
+	td->print_struct   = asn1_DEF_T5.print_struct;
+	td->last_tag_form  = asn1_DEF_T5.last_tag_form;
+	td->elements       = asn1_DEF_T5.elements;
+	td->elements_count = asn1_DEF_T5.elements_count;
+	td->specifics      = asn1_DEF_T5.specifics;
+}
+
+ber_dec_rval_t
+T4_decode_ber(asn1_TYPE_descriptor_t *td,
+		void **structure, void *bufptr, size_t size, int tag_mode) {
+	T4_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
+}
+
+der_enc_rval_t
+T4_encode_der(asn1_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	T4_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+int
+T4_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	T4_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+void
+T4_free(asn1_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	T4_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+
+/*** <<< STAT-DEFS [T4] >>> ***/
+
+static ber_tlv_tag_t asn1_DEF_T4_tags[] = {
+	(ASN_TAG_CLASS_CONTEXT | (5 << 2)),
+	(ASN_TAG_CLASS_CONTEXT | (6 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_T4 = {
+	"T4",
+	T4_constraint,
+	T4_decode_ber,
+	T4_encode_der,
+	T4_print,
+	T4_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_T4_tags,
+	sizeof(asn1_DEF_T4_tags)
+		/sizeof(asn1_DEF_T4_tags[0]), /* 2 */
+	-0,	/* Unknown yet */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+
+/*** <<< INCLUDES [T5] >>> ***/
+
+#include <T6.h>
+
+/*** <<< TYPE-DECLS [T5] >>> ***/
+
+
+typedef T6_t	 T5_t;
+
+/*** <<< FUNC-DECLS [T5] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_T5;
+asn_constr_check_f T5_constraint;
+ber_type_decoder_f T5_decode_ber;
+der_type_encoder_f T5_encode_der;
+asn_struct_print_f T5_print;
+asn_struct_free_f T5_free;
+
+/*** <<< CODE [T5] >>> ***/
+
+int
+T5_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_consume_bytes_f *app_errlog, void *app_key) {
+	
+	/* Make the underlying type checker permanent */
+	td->check_constraints = asn1_DEF_T6.check_constraints;
+	return td->check_constraints
+		(td, sptr, app_errlog, app_key);
+}
+
+/*
+ * This type is implemented using T6,
+ * so adjust the DEF appropriately.
+ */
+static void
+T5_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {
+	td->ber_decoder    = asn1_DEF_T6.ber_decoder;
+	td->der_encoder    = asn1_DEF_T6.der_encoder;
+	td->free_struct    = asn1_DEF_T6.free_struct;
+	td->print_struct   = asn1_DEF_T6.print_struct;
+	td->last_tag_form  = asn1_DEF_T6.last_tag_form;
+	td->elements       = asn1_DEF_T6.elements;
+	td->elements_count = asn1_DEF_T6.elements_count;
+	td->specifics      = asn1_DEF_T6.specifics;
+}
+
+ber_dec_rval_t
+T5_decode_ber(asn1_TYPE_descriptor_t *td,
+		void **structure, void *bufptr, size_t size, int tag_mode) {
+	T5_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
+}
+
+der_enc_rval_t
+T5_encode_der(asn1_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	T5_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+int
+T5_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	T5_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+void
+T5_free(asn1_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	T5_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+
+/*** <<< STAT-DEFS [T5] >>> ***/
+
+static ber_tlv_tag_t asn1_DEF_T5_tags[] = {
+	(ASN_TAG_CLASS_CONTEXT | (6 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_T5 = {
+	"T5",
+	T5_constraint,
+	T5_decode_ber,
+	T5_encode_der,
+	T5_print,
+	T5_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_T5_tags,
+	sizeof(asn1_DEF_T5_tags)
+		/sizeof(asn1_DEF_T5_tags[0]), /* 1 */
+	-0,	/* Unknown yet */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+
+/*** <<< INCLUDES [T6] >>> ***/
+
+#include <INTEGER.h>
+
+/*** <<< TYPE-DECLS [T6] >>> ***/
+
+
+typedef INTEGER_t	 T6_t;
+
+/*** <<< FUNC-DECLS [T6] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_T6;
+asn_constr_check_f T6_constraint;
+ber_type_decoder_f T6_decode_ber;
+der_type_encoder_f T6_encode_der;
+asn_struct_print_f T6_print;
+asn_struct_free_f T6_free;
+
+/*** <<< CODE [T6] >>> ***/
+
+int
+T6_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_consume_bytes_f *app_errlog, void *app_key) {
+	
+	/* Make the underlying type checker permanent */
+	td->check_constraints = asn1_DEF_INTEGER.check_constraints;
+	return td->check_constraints
+		(td, sptr, app_errlog, app_key);
+}
+
+/*
+ * This type is implemented using INTEGER,
+ * so adjust the DEF appropriately.
+ */
+static void
+T6_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {
+	td->ber_decoder    = asn1_DEF_INTEGER.ber_decoder;
+	td->der_encoder    = asn1_DEF_INTEGER.der_encoder;
+	td->free_struct    = asn1_DEF_INTEGER.free_struct;
+	td->print_struct   = asn1_DEF_INTEGER.print_struct;
+	td->last_tag_form  = asn1_DEF_INTEGER.last_tag_form;
+	td->elements       = asn1_DEF_INTEGER.elements;
+	td->elements_count = asn1_DEF_INTEGER.elements_count;
+	td->specifics      = asn1_DEF_INTEGER.specifics;
+}
+
+ber_dec_rval_t
+T6_decode_ber(asn1_TYPE_descriptor_t *td,
+		void **structure, void *bufptr, size_t size, int tag_mode) {
+	T6_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
+}
+
+der_enc_rval_t
+T6_encode_der(asn1_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	T6_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+int
+T6_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	T6_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+void
+T6_free(asn1_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	T6_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+
+/*** <<< STAT-DEFS [T6] >>> ***/
+
+static ber_tlv_tag_t asn1_DEF_T6_tags[] = {
+	(ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_T6 = {
+	"T6",
+	T6_constraint,
+	T6_decode_ber,
+	T6_encode_der,
+	T6_print,
+	T6_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_T6_tags,
+	sizeof(asn1_DEF_T6_tags)
+		/sizeof(asn1_DEF_T6_tags[0]), /* 1 */
+	-0,	/* Unknown yet */
+	0, 0,	/* No members */
+	0	/* No specifics */
+};
+
+
+/*** <<< INCLUDES [T] >>> ***/
+
+#include <Ts.h>
+
+/*** <<< TYPE-DECLS [T] >>> ***/
+
+
+typedef Ts_t	 T_t;
+
+/*** <<< FUNC-DECLS [T] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_T;
+asn_constr_check_f T_constraint;
+ber_type_decoder_f T_decode_ber;
+der_type_encoder_f T_encode_der;
+asn_struct_print_f T_print;
+asn_struct_free_f T_free;
+
+/*** <<< CODE [T] >>> ***/
+
+int
+T_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
+			asn_app_consume_bytes_f *app_errlog, void *app_key) {
+	
+	/* Make the underlying type checker permanent */
+	td->check_constraints = asn1_DEF_Ts.check_constraints;
+	return td->check_constraints
+		(td, sptr, app_errlog, app_key);
+}
+
+/*
+ * This type is implemented using Ts,
+ * so adjust the DEF appropriately.
+ */
+static void
+T_inherit_TYPE_descriptor(asn1_TYPE_descriptor_t *td) {
+	td->ber_decoder    = asn1_DEF_Ts.ber_decoder;
+	td->der_encoder    = asn1_DEF_Ts.der_encoder;
+	td->free_struct    = asn1_DEF_Ts.free_struct;
+	td->print_struct   = asn1_DEF_Ts.print_struct;
+	td->last_tag_form  = asn1_DEF_Ts.last_tag_form;
+	td->elements       = asn1_DEF_Ts.elements;
+	td->elements_count = asn1_DEF_Ts.elements_count;
+	td->specifics      = asn1_DEF_Ts.specifics;
+}
+
+ber_dec_rval_t
+T_decode_ber(asn1_TYPE_descriptor_t *td,
+		void **structure, void *bufptr, size_t size, int tag_mode) {
+	T_inherit_TYPE_descriptor(td);
+	return td->ber_decoder(td, structure, bufptr, size, tag_mode);
+}
+
+der_enc_rval_t
+T_encode_der(asn1_TYPE_descriptor_t *td,
+		void *structure, int tag_mode, ber_tlv_tag_t tag,
+		asn_app_consume_bytes_f *cb, void *app_key) {
+	T_inherit_TYPE_descriptor(td);
+	return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);
+}
+
+int
+T_print(asn1_TYPE_descriptor_t *td, const void *struct_ptr,
+		int ilevel, asn_app_consume_bytes_f *cb, void *app_key) {
+	T_inherit_TYPE_descriptor(td);
+	return td->print_struct(td, struct_ptr, ilevel, cb, app_key);
+}
+
+void
+T_free(asn1_TYPE_descriptor_t *td,
+		void *struct_ptr, int contents_only) {
+	T_inherit_TYPE_descriptor(td);
+	td->free_struct(td, struct_ptr, contents_only);
+}
+
+
+/*** <<< STAT-DEFS [T] >>> ***/
+
+static ber_tlv_tag_t asn1_DEF_T_tags[] = {
+	(ASN_TAG_CLASS_CONTEXT | (0 << 2))
+};
+asn1_TYPE_descriptor_t asn1_DEF_T = {
+	"T",
+	T_constraint,
+	T_decode_ber,
+	T_encode_der,
+	T_print,
+	T_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_T_tags,
+	sizeof(asn1_DEF_T_tags)
+		/sizeof(asn1_DEF_T_tags[0]), /* 1 */
+	-0,	/* Unknown yet */
+	0, 0,	/* Defined elsewhere */
+	0	/* No specifics */
+};
+
+
+/*** <<< INCLUDES [Ts] >>> ***/
+
+#include <T2.h>
+#include <T3.h>
+#include <constr_SEQUENCE.h>
+
+/*** <<< DEPS [Ts] >>> ***/
+
+extern asn1_TYPE_descriptor_t asn1_DEF_Ts;
+
+/*** <<< TYPE-DECLS [Ts] >>> ***/
+
+
+typedef struct Ts {
+	T2_t	 m1;
+	T3_t	*m2	/* OPTIONAL */;
+	T3_t	 m3;
+	
+	/* Context for parsing across buffer boundaries */
+	ber_dec_ctx_t _ber_dec_ctx;
+} Ts_t;
+
+/*** <<< STAT-DEFS [Ts] >>> ***/
+
+static asn1_TYPE_member_t asn1_MBR_Ts[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct Ts, m1),
+		.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
+		.tag_mode = -1,	/* IMPLICIT tag at current level */
+		.type = (void *)&asn1_DEF_T2,
+		.memb_constraints = 0,	/* Defer to actual type */
+		.name = "m1"
+		},
+	{ ATF_POINTER, 1, offsetof(struct Ts, m2),
+		.tag = (ASN_TAG_CLASS_CONTEXT | (2 << 2)),
+		.tag_mode = +1,	/* EXPLICIT tag at current level */
+		.type = (void *)&asn1_DEF_T3,
+		.memb_constraints = 0,	/* Defer to actual type */
+		.name = "m2"
+		},
+	{ ATF_NOFLAGS, 0, offsetof(struct Ts, m3),
+		.tag = (ASN_TAG_CLASS_CONTEXT | (3 << 2)),
+		.tag_mode = -1,	/* IMPLICIT tag at current level */
+		.type = (void *)&asn1_DEF_T3,
+		.memb_constraints = 0,	/* Defer to actual type */
+		.name = "m3"
+		},
+};
+static ber_tlv_tag_t asn1_DEF_Ts_tags[] = {
+	(ASN_TAG_CLASS_CONTEXT | (123 << 2))
+};
+static asn1_TYPE_tag2member_t asn1_DEF_Ts_tag2el[] = {
+    { (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 0, 0, 0 }, /* m1 at 24 */
+    { (ASN_TAG_CLASS_CONTEXT | (2 << 2)), 1, 0, 0 }, /* m2 at 25 */
+    { (ASN_TAG_CLASS_CONTEXT | (3 << 2)), 2, 0, 0 }, /* m3 at 27 */
+};
+static asn1_SEQUENCE_specifics_t asn1_DEF_Ts_specs = {
+	sizeof(struct Ts),
+	offsetof(struct Ts, _ber_dec_ctx),
+	asn1_DEF_Ts_tag2el,
+	3,	/* Count of tags in the map */
+	-1,	/* Start extensions */
+	-1	/* Stop extensions */
+};
+asn1_TYPE_descriptor_t asn1_DEF_Ts = {
+	"Ts",
+	SEQUENCE_constraint,
+	SEQUENCE_decode_ber,
+	SEQUENCE_encode_der,
+	SEQUENCE_print,
+	SEQUENCE_free,
+	0,	/* Use generic outmost tag fetcher */
+	asn1_DEF_Ts_tags,
+	sizeof(asn1_DEF_Ts_tags)
+		/sizeof(asn1_DEF_Ts_tags[0]), /* 1 */
+	1,	/* Whether CONSTRUCTED */
+	asn1_MBR_Ts,
+	3,	/* Elements count */
+	&asn1_DEF_Ts_specs	/* Additional specs */
+};
+