/*
 * Don't look into this file. First, because it's a mess, and second, because
 * it's a brain of the compiler, and you don't wanna mess with brains do you? ;)
 */
#include "asn1c_internal.h"
#include "asn1c_C.h"
#include "asn1c_constraint.h"
#include "asn1c_out.h"
#include "asn1c_misc.h"
#include "asn1c_ioc.h"
#include <asn1fix_crange.h>	/* constraint groker from libasn1fix */
#include <asn1fix_export.h>	/* other exportables from libasn1fix */
#include <asn1parser.h>

typedef struct tag2el_s {
	struct asn1p_type_tag_s el_tag;
	int el_no;
	int toff_first;
	int toff_last;
	asn1p_expr_t *from_expr;
} tag2el_t;

typedef enum fte {
	FTE_ALLTAGS,
	FTE_CANONICAL_XER,
} fte_e;
static int _fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags);
static int _add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags);

enum onc_flags {
	ONC_noflags		= 0x00,
	ONC_avoid_keywords	= 0x01,
	ONC_force_compound_name	= 0x02,
};
static int out_name_chain(arg_t *arg, enum onc_flags);
static int asn1c_lang_C_type_SEQUENCE_def(
    arg_t *arg, asn1c_ioc_table_and_objset_t *);
static int asn1c_lang_C_type_SET_def(arg_t *arg);
static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
static int asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of);
static int _print_tag(arg_t *arg, struct asn1p_type_tag_s *tag_p);
static int compute_extensions_start(asn1p_expr_t *expr);
static int expr_break_recursion(arg_t *arg, asn1p_expr_t *expr);
static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr);
static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
static int emit_single_member_OER_constraint_value(arg_t *arg, asn1cnst_range_t *range);
static int emit_single_member_OER_constraint_size(arg_t *arg, asn1cnst_range_t *range);
static int emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int juscountvalues, const char *type);
static int emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
static int emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx);
static int emit_member_table(arg_t *arg, asn1p_expr_t *expr,
                             asn1c_ioc_table_and_objset_t *);
static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier);
static int emit_include_dependencies(arg_t *arg);
static asn1p_expr_t *terminal_structable(arg_t *arg, asn1p_expr_t *expr);
static int expr_defined_recursively(arg_t *arg, asn1p_expr_t *expr);
static int asn1c_recurse(arg_t *arg, asn1p_expr_t *expr, int (*callback)(arg_t *arg, void *key), void *key);
static asn1p_expr_type_e expr_get_type(arg_t *arg, asn1p_expr_t *expr);
static int try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out);
static int *compute_canonical_members_order(arg_t *arg, int el_count);

enum tvm_compat {
	_TVM_SAME	= 0,	/* tags and all_tags are same */
	_TVM_SUBSET	= 1,	/* tags are subset of all_tags */
	_TVM_DIFFERENT	= 2,	/* tags and all_tags are different */
};
static enum tvm_compat emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tc, int *atc);

enum etd_spec {
	ETD_NO_SPECIFICS,
	ETD_HAS_SPECIFICS
};
static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec);

#define	C99_MODE	(!(arg->flags & A1C_NO_C99))
#define	UNNAMED_UNIONS	(arg->flags & A1C_UNNAMED_UNIONS)
#define	HIDE_INNER_DEFS	(arg->embed && !(arg->flags & A1C_ALL_DEFS_GLOBAL))

#define	PCTX_DEF INDENTED(		\
	OUT("\n");			\
	OUT("/* Context for parsing across buffer boundaries */\n");	\
	OUT("asn_struct_ctx_t _asn_ctx;\n"));


#define	DEPENDENCIES	do {						\
	emit_include_dependencies(arg);					\
	if(expr->expr_type == ASN_CONSTR_SET_OF)			\
		GEN_INCLUDE_STD("asn_SET_OF");				\
	if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF)			\
		GEN_INCLUDE_STD("asn_SEQUENCE_OF");			\
} while(0)

/* MKID_safe() without checking for reserved keywords */
#define	MKID(expr)	(asn1c_make_identifier(0, expr, 0))
#define	MKID_safe(expr)	(asn1c_make_identifier(AMI_CHECK_RESERVED, expr, 0))

int
asn1c_lang_C_type_REAL(arg_t *arg) {
	return asn1c_lang_C_type_SIMPLE_TYPE(arg);
}

struct value2enum {
	asn1c_integer_t	 value;
	const char	*name;
	int		 idx;
};
static int compar_enumMap_byName(const void *ap, const void *bp) {
	const struct value2enum *a = (const struct value2enum *)ap;
	const struct value2enum *b = (const struct value2enum *)bp;
	return strcmp(a->name, b->name);
}
static int compar_enumMap_byValue(const void *ap, const void *bp) {
	const struct value2enum *a = (const struct value2enum *)ap;
	const struct value2enum *b = (const struct value2enum *)bp;
	if(a->value < b->value)
		return -1;
	else if(a->value == b->value)
		return 0;
	return 1;
}

int
asn1c_lang_C_type_common_INTEGER(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	int el_count = expr_elements_count(arg, expr);
	struct value2enum *v2e;
	int map_extensions = (expr->expr_type == ASN_BASIC_INTEGER);
	int eidx;
	int saved_target = arg->target->target;

	v2e = alloca((el_count + 1) * sizeof(*v2e));

	/*
	 * For all ENUMERATED types and for those INTEGER types which
	 * have identifiers, print out an enumeration table.
	 */
	if(expr->expr_type == ASN_BASIC_ENUMERATED || el_count) {
		eidx = 0;
		REDIR(OT_DEPS);
		OUT("typedef enum ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(" {\n");
		TQ_FOR(v, &(expr->members), next) {
			switch(v->expr_type) {
			case A1TC_UNIVERVAL:
				OUT("\t");
				out_name_chain(arg, ONC_noflags);
				OUT("_%s", MKID(v));
				OUT("\t= %s%s\n",
					asn1p_itoa(v->value->value.v_integer),
					(eidx+1 < el_count) ? "," : "");
				v2e[eidx].name = v->Identifier;
				v2e[eidx].value = v->value->value.v_integer;
				eidx++;
				break;
			case A1TC_EXTENSIBLE:
				OUT("\t/*\n");
				OUT("\t * Enumeration is extensible\n");
				OUT("\t */\n");
				if(!map_extensions)
					map_extensions = eidx + 1;
				break;
			default:
				return -1;
			}
		}
		OUT("} e_");
			out_name_chain(arg, ONC_noflags);
		OUT(";\n");
		assert(eidx == el_count);
	}

	/*
	 * For all ENUMERATED types print out a mapping table
	 * between identifiers and associated values.
	 * This is prohibited for INTEGER types by by X.693:8.3.4.
	 */
	if(expr->expr_type == ASN_BASIC_ENUMERATED) {

		/*
		 * Generate a enumerationName<->value map for XER codec.
		 */
		REDIR(OT_STAT_DEFS);

		OUT("static const asn_INTEGER_enum_map_t asn_MAP_%s_value2enum_%d[] = {\n",
			MKID(expr), expr->_type_unique_index);
		qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byValue);
		for(eidx = 0; eidx < el_count; eidx++) {
			v2e[eidx].idx = eidx;
			OUT("\t{ %s,\t%ld,\t\"%s\" }%s\n",
				asn1p_itoa(v2e[eidx].value),
				(long)strlen(v2e[eidx].name), v2e[eidx].name,
				(eidx + 1 < el_count) ? "," : "");
		}
		if(map_extensions)
			OUT("\t/* This list is extensible */\n");
		OUT("};\n");

		OUT("static const unsigned int asn_MAP_%s_enum2value_%d[] = {\n",
			MKID(expr), expr->_type_unique_index);
		qsort(v2e, el_count, sizeof(v2e[0]), compar_enumMap_byName);
		for(eidx = 0; eidx < el_count; eidx++) {
			OUT("\t%d%s\t/* %s(%s) */\n",
				v2e[eidx].idx,
				(eidx + 1 < el_count) ? "," : "",
				v2e[eidx].name, asn1p_itoa(v2e[eidx].value));
		}
		if(map_extensions)
			OUT("\t/* This list is extensible */\n");
		OUT("};\n");

		if(!(expr->_type_referenced)) OUT("static ");
		OUT("const asn_INTEGER_specifics_t asn_SPC_%s_specs_%d = {\n",
			MKID(expr), expr->_type_unique_index);
		INDENT(+1);
		OUT("asn_MAP_%s_value2enum_%d,\t"
			"/* \"tag\" => N; sorted by tag */\n",
			MKID(expr),
			expr->_type_unique_index);
		OUT("asn_MAP_%s_enum2value_%d,\t"
			"/* N => \"tag\"; sorted by N */\n",
			MKID(expr),
			expr->_type_unique_index);
		OUT("%d,\t/* Number of elements in the maps */\n",
			el_count);
		if(map_extensions) {
			OUT("%d,\t/* Extensions before this member */\n",
				map_extensions);
		} else {
			OUT("0,\t/* Enumeration is not extensible */\n");
		}
		if(expr->expr_type == ASN_BASIC_ENUMERATED)
			OUT("1,\t/* Strict enumeration */\n");
		else
			OUT("0,\n");
		OUT("0,\t/* Native long size */\n");
		OUT("0\n");
		INDENT(-1);
		OUT("};\n");
	}

	if(expr->expr_type == ASN_BASIC_INTEGER
	&& asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN) {
		REDIR(OT_STAT_DEFS);
		if(!(expr->_type_referenced)) OUT("static ");
		OUT("const asn_INTEGER_specifics_t asn_SPC_%s_specs_%d = {\n",
			MKID(expr), expr->_type_unique_index);
		INDENT(+1);
		OUT("0,\t");
		OUT("0,\t");
		OUT("0,\t");
		OUT("0,\t");
		OUT("0,\n");
		OUT("0,\t/* Native long size */\n");
		OUT("1\t/* Unsigned representation */\n");
		INDENT(-1);
		OUT("};\n");
	}

	REDIR(saved_target);

	return asn1c_lang_C_type_SIMPLE_TYPE(arg);
}

int
asn1c_lang_C_type_BIT_STRING(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	int el_count = expr_elements_count(arg, expr);
	int saved_target = arg->target->target;

	if(el_count) {
		int eidx = 0;
		REDIR(OT_DEPS);
		OUT("typedef enum ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(" {\n");
		TQ_FOR(v, &(expr->members), next) {
			if(v->expr_type != A1TC_UNIVERVAL) {
				OUT("/* Unexpected BIT STRING element: %s */\n",
				v->Identifier);
				continue;
			}
			eidx++;
			OUT("\t");
			out_name_chain(arg, ONC_noflags);
			OUT("_%s", MKID(v));
			OUT("\t= %s%s\n",
				asn1p_itoa(v->value->value.v_integer),
				(eidx < el_count) ? "," : "");
		}
		OUT("} e_");
			out_name_chain(arg, ONC_noflags);
		OUT(";\n");
		assert(eidx == el_count);
	}

	REDIR(saved_target);

	return asn1c_lang_C_type_SIMPLE_TYPE(arg);
}

int
asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	int comp_mode = 0;	/* {root,ext=1,root,root,...} */
	int saved_target = arg->target->target;
    asn1c_ioc_table_and_objset_t ioc_tao;

	DEPENDENCIES;

    ioc_tao = asn1c_get_ioc_table(arg);
    if(ioc_tao.ioct) {
        if(emit_ioc_table(arg, expr, ioc_tao)) {
            return -1;
        }
    } else if(ioc_tao.fatal_error) {
        return -1;
    }

	if(arg->embed) {

		/* Use _anonymous_type field to indicate it's called from
		 * asn1c_lang_C_type_SEx_OF() */
		if (expr->_anonymous_type) {
			REDIR(OT_FWD_DEFS);
			OUT("typedef ");
		}
		OUT("struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(" {\n");
	} else {
		REDIR(OT_TYPE_DECLS);
		OUT("typedef struct %s {\n",
			MKID_safe(expr));
	}

	TQ_FOR(v, &(expr->members), next) {
		if(v->expr_type == A1TC_EXTENSIBLE)
			if(comp_mode < 3) comp_mode++;
		if(comp_mode == 1)
			v->marker.flags |= EM_OMITABLE | EM_INDIRECT;
		try_inline_default(arg, v, 1);
		EMBED_WITH_IOCT(v, ioc_tao);
	}

	PCTX_DEF;

	if (arg->embed && expr->_anonymous_type) {
		OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
		out_name_chain(arg, ONC_avoid_keywords);
		OUT("%s;\n", arg->embed ? "" : "_t");

		REDIR(saved_target);

		OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
			out_name_chain(arg, ONC_avoid_keywords);
	} else {
		OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
		expr->_anonymous_type ? "" :
			arg->embed
				? MKID_safe(expr)
				: MKID(expr),
		arg->embed ? "" : "_t");
	}

	return asn1c_lang_C_type_SEQUENCE_def(arg, ioc_tao.ioct ? &ioc_tao : 0);
}

static int
asn1c_lang_C_type_SEQUENCE_def(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	int elements;	/* Number of elements */
	int ext_start = -2;
	int ext_stop = -2;
	tag2el_t *tag2el = NULL;
	int tag2el_count = 0;
	int tags_count;
	int all_tags_count;
	enum tvm_compat tv_mode;
	int roms_count;		/* Root optional members */
	int aoms_count;		/* Additions optional members */
	int saved_target = arg->target->target;

	/*
	 * Fetch every inner tag from the tag to elements map.
	 */
	if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1, FTE_ALLTAGS)) {
		if(tag2el) free(tag2el);
		return -1;
	}

	GEN_INCLUDE_STD("constr_SEQUENCE");
	if(!arg->embed)
		GEN_DECLARE("SEQUENCE", expr);	/* asn_DEF_xxx */

	REDIR(OT_STAT_DEFS);

	/*
	 * Print out the table according to which parsing is performed.
	 */
	if(expr_elements_count(arg, expr)) {
		int comp_mode = 0;	/* {root,ext=1,root,root,...} */

		if(!(expr->_type_referenced)) OUT("static ");
		OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
			MKID(expr), expr->_type_unique_index);

		elements = 0;
		roms_count = 0;
		aoms_count = 0;
		INDENTED(TQ_FOR(v, &(expr->members), next) {
			if(v->expr_type == A1TC_EXTENSIBLE) {
				if((++comp_mode) == 1)
					ext_start = elements - 1;
				else
					ext_stop = elements - 1;
				continue;
			}
			if(v->marker.flags & EM_OMITABLE)
			    comp_mode == 1 ? ++aoms_count : ++roms_count;
			emit_member_table(arg, v, opt_ioc);
			elements++;
		});
		OUT("};\n");

		if((roms_count + aoms_count) && (arg->flags & (A1C_GEN_OER|A1C_GEN_PER))) {
			int elm = 0;
			int comma = 0;
			comp_mode = 0;
			OUT("static const int asn_MAP_%s_oms_%d[] = {",
				MKID(expr),
				expr->_type_unique_index);
			TQ_FOR(v, &(expr->members), next) {
				if(v->expr_type == A1TC_EXTENSIBLE) {
					++comp_mode;
					continue;
				}
				if((v->marker.flags & EM_OMITABLE)
				&& comp_mode != 1) {
					if(!comma) comma++;
					else OUT(",");
					OUT(" %d", elm);
				}
				++elm;
			}
			elm = 0;
			comp_mode = 0;
			TQ_FOR(v, &(expr->members), next) {
				if(v->expr_type == A1TC_EXTENSIBLE) {
					++comp_mode;
					continue;
				}
				if((v->marker.flags & EM_OMITABLE)
				&& comp_mode == 1) {
					if(!comma) comma++;
					else OUT(",");
					OUT(" %d", elm);
				}
				++elm;
			}
			OUT(" };\n");
			if(roms_count > 65536) {
				FATAL("Too many optional elements in %s "
					"at line %d!",
					arg->expr->Identifier,
					arg->expr->_lineno);
                return -1;
            }
		} else {
			roms_count = 0;
			aoms_count = 0;
		}
	} else {
		elements = 0;
		roms_count = 0;
		aoms_count = 0;
	}

	/*
	 * Print out asn_DEF_<type>_[all_]tags[] vectors.
	 */
	tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);

	/*
	 * Tags to elements map.
	 */
	emit_tag2member_map(arg, tag2el, tag2el_count, 0);

	if(!(expr->_type_referenced)) OUT("static ");
	OUT("asn_SEQUENCE_specifics_t asn_SPC_%s_specs_%d = {\n",
		MKID(expr), expr->_type_unique_index);
	INDENT(+1);
	OUT("sizeof(struct ");
		out_name_chain(arg, ONC_avoid_keywords); OUT("),\n");
	OUT("offsetof(struct ");
		out_name_chain(arg, ONC_avoid_keywords); OUT(", _asn_ctx),\n");

	if(tag2el_count) {
		OUT("asn_MAP_%s_tag2el_%d,\n",
			MKID(expr),
			expr->_type_unique_index);
		OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
	} else {
		OUT("0,\t/* No top level tags */\n");
		OUT("0,\t/* No tags in the map */\n");
	}
	if(roms_count + aoms_count) {
		OUT("asn_MAP_%s_oms_%d,\t/* Optional members */\n",
			MKID(expr), expr->_type_unique_index);
		OUT("%d, %d,\t/* Root/Additions */\n", roms_count, aoms_count);
	} else {
		OUT("0, 0, 0,\t/* Optional elements (not needed) */\n");
	}
	OUT("%d,\t/* Start extensions */\n",
			ext_start<0 ? -1 : ext_start);
	OUT("%d\t/* Stop extensions */\n",
			(ext_stop<ext_start)?elements+1:(ext_stop<0?-1:ext_stop));
	INDENT(-1);
	OUT("};\n");

	/*
	 * Emit asn_DEF_xxx table.
	 */
	emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
			ETD_HAS_SPECIFICS);

	REDIR(saved_target);

	if(tag2el) free(tag2el);

	return 0;
} /* _SEQUENCE_def() */

int
asn1c_lang_C_type_SET(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	long mcount;
	char *id;
	int comp_mode = 0;	/* {root,ext=1,root,root,...} */
	int saved_target = arg->target->target;

	DEPENDENCIES;

	REDIR(OT_DEPS);

	OUT("\n");
	OUT("/*\n");
	OUT(" * Method of determining the components presence\n");
	OUT(" */\n");
	mcount = 0;
	OUT("typedef enum ");
		out_name_chain(arg, ONC_noflags);
	OUT("_PR {\n");
	TQ_FOR(v, &(expr->members), next) {
		if(v->expr_type == A1TC_EXTENSIBLE) continue;
		INDENTED(
			out_name_chain(arg, ONC_noflags);
			OUT("_PR_");
			id = MKID(v);
			OUT("%s,\t/* Member %s is present */\n",
				id, id)
		);
		mcount++;
	}
	OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");

	REDIR(saved_target);

	if(arg->embed) {
		if (expr->_anonymous_type) {
			REDIR(OT_FWD_DEFS);
			OUT("typedef ");
		}
		OUT("struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(" {\n");
	} else {
		REDIR(OT_TYPE_DECLS);
		OUT("typedef struct %s {\n",
			MKID_safe(expr));
	}

	TQ_FOR(v, &(expr->members), next) {
		if(v->expr_type == A1TC_EXTENSIBLE)
			if(comp_mode < 3) comp_mode++;
		if(comp_mode == 1)
			v->marker.flags |= EM_OMITABLE | EM_INDIRECT;
		try_inline_default(arg, v, 1);
		EMBED(v);
	}

	INDENTED(
		id = MKID(expr);
		OUT("\n");
		OUT("/* Presence bitmask: ASN_SET_ISPRESENT(p%s, %s_PR_x) */\n",
			id, id);
		OUT("unsigned int _presence_map\n");
		OUT("\t[((%ld+(8*sizeof(unsigned int))-1)/(8*sizeof(unsigned int)))];\n", mcount);
	);

	PCTX_DEF;

	if (arg->embed && expr->_anonymous_type) {
		OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
		out_name_chain(arg, ONC_avoid_keywords);
		OUT("%s;\n", arg->embed ? "" : "_t");

		REDIR(saved_target);

		OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
			out_name_chain(arg, ONC_avoid_keywords);
	} else {
		OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			expr->_anonymous_type ? "" : MKID_safe(expr),
			arg->embed ? "" : "_t");
	}

	return asn1c_lang_C_type_SET_def(arg);
}

static int
asn1c_lang_C_type_SET_def(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	int elements;
	tag2el_t *tag2el = NULL;
	int tag2el_count = 0;
	tag2el_t *tag2el_cxer = NULL;
	int tag2el_cxer_count = 0;
	int tags_count;
	int all_tags_count;
	enum tvm_compat tv_mode;
	char *p;
	int saved_target = arg->target->target;

	/*
	 * Fetch every inner tag from the tag to elements map.
	 */
	if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1, FTE_ALLTAGS)) {
		if(tag2el) free(tag2el);
		return -1;
	}
	if(_fill_tag2el_map(arg, &tag2el_cxer, &tag2el_cxer_count, -1, FTE_CANONICAL_XER)) {
		if(tag2el) free(tag2el);
		if(tag2el_cxer) free(tag2el_cxer);
		return -1;
	}
	if(tag2el_cxer_count == tag2el_count
	&& memcmp(tag2el, tag2el_cxer, tag2el_count) == 0) {
		free(tag2el_cxer);
		tag2el_cxer = 0;
	}

	GEN_INCLUDE_STD("constr_SET");
	if(!arg->embed)
		GEN_DECLARE("SET", expr);	/* asn_DEF_xxx */

	REDIR(OT_STAT_DEFS);

	/*
	 * Print out the table according to which parsing is performed.
	 */
	if(expr_elements_count(arg, expr)) {
		int comp_mode = 0;	/* {root,ext=1,root,root,...} */

		if(!(expr->_type_referenced)) OUT("static ");
		OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
			MKID(expr), expr->_type_unique_index);

		elements = 0;
		INDENTED(TQ_FOR(v, &(expr->members), next) {
			if(v->expr_type == A1TC_EXTENSIBLE) {
				if(comp_mode < 3) comp_mode++;
			} else {
				emit_member_table(arg, v, NULL);
				elements++;
			}
		});
		OUT("};\n");
	} else {
		elements = 0;
	}

	/*
	 * Print out asn_DEF_<type>_[all_]tags[] vectors.
	 */
	tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);

	/*
	 * Tags to elements map.
	 */
	emit_tag2member_map(arg, tag2el, tag2el_count, 0);
	if(tag2el_cxer)
	emit_tag2member_map(arg, tag2el_cxer, tag2el_cxer_count, "_cxer");

	/*
	 * Emit a map of mandatory elements.
	 */
	OUT("static const uint8_t asn_MAP_%s_mmap_%d",
		MKID(expr), expr->_type_unique_index);
	p = MKID_safe(expr);
	OUT("[(%d + (8 * sizeof(unsigned int)) - 1) / 8]", elements);
	OUT(" = {\n");
	INDENTED(
	if(elements) {
		int el = 0;
		TQ_FOR(v, &(expr->members), next) {
			if(v->expr_type == A1TC_EXTENSIBLE) continue;
			if(el) {
				if((el % 8) == 0)
					OUT(",\n");
				else
					OUT(" | ");
			}
			OUT("(%d << %d)",
				(v->marker.flags & EM_OMITABLE) != EM_OMITABLE,
				7 - (el % 8));
			el++;
		}
	} else {
		OUT("0");
	}
	);
	OUT("\n");
	OUT("};\n");

	if(!(expr->_type_referenced)) OUT("static \n");
	OUT("asn_SET_specifics_t asn_SPC_%s_specs_%d = {\n",
		MKID(expr), expr->_type_unique_index);
	INDENTED(
		OUT("sizeof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT("),\n");
		OUT("offsetof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(", _asn_ctx),\n");
		OUT("offsetof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(", _presence_map),\n");
		p = MKID(expr);
		OUT("asn_MAP_%s_tag2el_%d,\n", p, expr->_type_unique_index);
		OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
		if(tag2el_cxer)
			OUT("asn_MAP_%s_tag2el_cxer_%d,\n",
				p, expr->_type_unique_index);
		else
			OUT("asn_MAP_%s_tag2el_%d,\t/* Same as above */\n",
				p, expr->_type_unique_index);
		OUT("%d,\t/* Count of tags in the CXER map */\n",
			tag2el_cxer_count);
		OUT("%d,\t/* Whether extensible */\n",
			compute_extensions_start(expr) == -1 ? 0 : 1);
		OUT("(const unsigned int *)asn_MAP_%s_mmap_%d\t/* Mandatory elements map */\n",
			p, expr->_type_unique_index);
	);
	OUT("};\n");

	/*
	 * Emit asn_DEF_xxx table.
	 */
	emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
			ETD_HAS_SPECIFICS);

	REDIR(saved_target);

	if (tag2el) free(tag2el);
	if (tag2el_cxer) free(tag2el_cxer);

	return 0;
} /* _SET_def() */

int
asn1c_lang_C_type_SEx_OF(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *memb = TQ_FIRST(&expr->members);
	int saved_target = arg->target->target;

	DEPENDENCIES;

	if(arg->embed) {
		if (expr->_anonymous_type) {
			REDIR(OT_FWD_DEFS);
			OUT("typedef ");
		}
		OUT("struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(" {\n");
	} else {
		OUT("typedef struct %s {\n", MKID_safe(expr));
	}

	INDENT(+1);
	OUT("A_%s_OF(",
		(arg->expr->expr_type == ASN_CONSTR_SET_OF)
			? "SET" : "SEQUENCE");

	/*
	 * README README
	 * The implementation of the A_SET_OF() macro is already indirect.
	 */
	memb->marker.flags |= EM_INDIRECT;

	if(memb->expr_type & ASN_CONSTR_MASK
	|| ((memb->expr_type == ASN_BASIC_ENUMERATED
		|| (0 /* -- prohibited by X.693:8.3.4 */
			&& memb->expr_type == ASN_BASIC_INTEGER))
	    	&& expr_elements_count(arg, memb))) {
		arg_t tmp;
		asn1p_expr_t tmp_memb;
		arg->embed++;
			tmp = *arg;
			tmp.expr = &tmp_memb;
			tmp_memb = *memb;
			tmp_memb.marker.flags &= ~EM_INDIRECT;
			tmp_memb._anonymous_type = 1;
			if(tmp_memb.Identifier == 0) {
				tmp_memb.Identifier = "Member";
				if(0)
				tmp_memb.Identifier = strdup(
					asn1c_make_identifier(0,
						expr, "Member", 0));
				assert(tmp_memb.Identifier);
			}
			tmp.default_cb(&tmp, NULL);
			if(tmp_memb.Identifier != memb->Identifier)
				if(0) free(tmp_memb.Identifier);
		arg->embed--;
		assert(arg->target->target == OT_TYPE_DECLS ||
				arg->target->target == OT_FWD_DEFS);
	} else {
		OUT("%s", asn1c_type_name(arg, memb,
			(memb->marker.flags & EM_UNRECURSE)
				? TNF_RSAFE : TNF_CTYPE));
	}
	/* README README (above) */
	if(0 && (memb->marker.flags & EM_INDIRECT))
		OUT(" *");
	OUT(") list;\n");
	INDENT(-1);

	PCTX_DEF;

	if (arg->embed && expr->_anonymous_type) {
		OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
		out_name_chain(arg, ONC_avoid_keywords);
		OUT("%s;\n", arg->embed ? "" : "_t");

		REDIR(saved_target);

		OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
			out_name_chain(arg, ONC_avoid_keywords);
	} else {
		OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			expr->_anonymous_type ? "" : MKID_safe(expr),
			arg->embed ? "" : "_t");
	}

	/*
	 * SET OF/SEQUENCE OF definition
	 */
	return asn1c_lang_C_type_SEx_OF_def(arg,
		(arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF));
}

static int
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_count;
	int all_tags_count;
	enum tvm_compat tv_mode;
	int saved_target = arg->target->target;

	/*
	 * Print out the table according to which parsing is performed.
	 */
	if(seq_of) {
		GEN_INCLUDE_STD("constr_SEQUENCE_OF");
	} else {
		GEN_INCLUDE_STD("constr_SET_OF");
	}
	if(!arg->embed)
		GEN_DECLARE("SET_OF", expr);	/* asn_DEF_xxx */

	REDIR(OT_STAT_DEFS);

	/*
	 * Print out the table according to which parsing is performed.
	 */
	if(!(expr->_type_referenced)) OUT("static ");
	OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
		MKID(expr), expr->_type_unique_index);
	INDENT(+1);
		v = TQ_FIRST(&(expr->members));
		if(!v->Identifier) {
			v->Identifier = strdup("Member");
			assert(v->Identifier);
		}
		v->_anonymous_type = 1;
		arg->embed++;
		emit_member_table(arg, v, NULL);
		arg->embed--;
		free(v->Identifier);
		v->Identifier = (char *)NULL;
	INDENT(-1);
	OUT("};\n");

	/*
	 * Print out asn_DEF_<type>_[all_]tags[] vectors.
	 */
	tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);

	if(!(expr->_type_referenced)) OUT("static ");
	OUT("asn_SET_OF_specifics_t asn_SPC_%s_specs_%d = {\n",
		MKID(expr), expr->_type_unique_index);
	INDENTED(
		OUT("sizeof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT("),\n");
		OUT("offsetof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(", _asn_ctx),\n");
		{
		int as_xvl = expr_as_xmlvaluelist(arg, v);
		OUT("%d,\t/* XER encoding is %s */\n",
			as_xvl,
			as_xvl ? "XMLValueList" : "XMLDelimitedItemList");
		}
	);
	OUT("};\n");

	/*
	 * Emit asn_DEF_xxx table.
	 */
	emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, 1,
			ETD_HAS_SPECIFICS);

	REDIR(saved_target);

	return 0;
} /* _SEx_OF_def() */

int
asn1c_lang_C_type_CHOICE(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	char *id;
	int saved_target = arg->target->target;

	DEPENDENCIES;

	REDIR(OT_DEPS);

	OUT("typedef enum ");
		out_name_chain(arg, ONC_noflags);
	OUT("_PR {\n");
	INDENTED(
		int skipComma = 1;
		out_name_chain(arg, ONC_noflags);
		OUT("_PR_NOTHING,\t/* No components present */\n");
		TQ_FOR(v, &(expr->members), next) {
			if(skipComma) skipComma = 0;
			else if (v->expr_type == A1TC_EXTENSIBLE && !TQ_NEXT(v, next)) OUT("\n");
			else OUT(",\n");
			if(v->expr_type == A1TC_EXTENSIBLE) {
				OUT("/* Extensions may appear below */\n");
				skipComma = 1;
				continue;
			}
			out_name_chain(arg, ONC_noflags);
			id = MKID(v);
			OUT("_PR_%s", id);
		}
		OUT("\n");
	);
	OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");

	REDIR(saved_target);

	if(arg->embed) {
		if (expr->_anonymous_type) {
			REDIR(OT_FWD_DEFS);
			OUT("typedef ");
		}
		OUT("struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(" {\n");
	} else {
		REDIR(OT_TYPE_DECLS);
		OUT("typedef struct %s {\n", MKID_safe(expr));
	}

	INDENTED(
		out_name_chain(arg, ONC_noflags);
		OUT("_PR present;\n");
		OUT("union ");
		if(UNNAMED_UNIONS == 0) {
			out_name_chain(arg, ONC_force_compound_name);
			OUT("_u ");
		}
		OUT("{\n");
		TQ_FOR(v, &(expr->members), next) {
			EMBED(v);
		}
		if(UNNAMED_UNIONS)	OUT("};\n");
		else			OUT("} choice;\n");
	);

	PCTX_DEF;

	if (arg->embed && expr->_anonymous_type) {
		OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
		out_name_chain(arg, ONC_avoid_keywords);
		OUT("%s;\n", arg->embed ? "" : "_t");

		REDIR(saved_target);

		OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
			out_name_chain(arg, ONC_avoid_keywords);
	} else {
		OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			expr->_anonymous_type ? "" :
				arg->embed
					? MKID_safe(expr)
					: MKID(expr),
			arg->embed ? "" : "_t");
	}

	return asn1c_lang_C_type_CHOICE_def(arg);
}

static int
asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *v;
	int elements;	/* Number of elements */
	tag2el_t *tag2el = NULL;
	int tag2el_count = 0;
	int tags_count;
	int all_tags_count;
	enum tvm_compat tv_mode;
	int *cmap = 0;
	int saved_target = arg->target->target;

	/*
	 * Fetch every inner tag from the tag to elements map.
	 */
	if(_fill_tag2el_map(arg, &tag2el, &tag2el_count, -1, FTE_ALLTAGS)) {
		if(tag2el) free(tag2el);
		return -1;
	}

	GEN_INCLUDE_STD("constr_CHOICE");
	if(!arg->embed)
		GEN_DECLARE("CHOICE", expr);	/* asn_DEF_xxx */

	REDIR(OT_STAT_DEFS);

	/*
	 * Print out the table according to which parsing is performed.
	 */
	if(expr_elements_count(arg, expr)) {

		if(!(expr->_type_referenced)) OUT("static ");
		OUT("asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
			MKID(expr), expr->_type_unique_index);

		elements = 0;
		INDENTED(TQ_FOR(v, &(expr->members), next) {
			if(v->expr_type == A1TC_EXTENSIBLE)
				continue;
			emit_member_table(arg, v, NULL);
			elements++;
		});
		OUT("};\n");
	} else {
		elements = 0;
	}

	/* Create a canonical elements map */
	if(elements && (arg->flags & A1C_GEN_PER)) {
		int i;
		cmap = compute_canonical_members_order(arg, elements);
		if(cmap) {
			OUT("static const int asn_MAP_%s_cmap_%d[] = {",
				MKID(expr),
				expr->_type_unique_index);
			for(i = 0; i < elements; i++) {
				if(i) OUT(",");
				OUT(" %d", cmap[i]);
			}
			OUT(" };\n");
			free(cmap);
		}
	}

	if(arg->embed) {
		/*
		 * Our parent structure has already taken this into account.
		 */
		tv_mode = _TVM_SAME;
		tags_count = all_tags_count = 0;
	} else {
		tv_mode = emit_tags_vectors(arg, expr,
			&tags_count, &all_tags_count);
	}

	/*
	 * Tags to elements map.
	 */
	emit_tag2member_map(arg, tag2el, tag2el_count, 0);

	if(!(expr->_type_referenced)) OUT("static ");
	OUT("asn_CHOICE_specifics_t asn_SPC_%s_specs_%d = {\n",
		MKID(expr), expr->_type_unique_index);
	INDENTED(
		OUT("sizeof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT("),\n");
		OUT("offsetof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(", _asn_ctx),\n");
		OUT("offsetof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(", present),\n");
		OUT("sizeof(((struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(" *)0)->present),\n");
		OUT("asn_MAP_%s_tag2el_%d,\n",
			MKID(expr), expr->_type_unique_index);
		OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
		if(C99_MODE) OUT(".canonical_order = ");
		if(cmap) OUT("asn_MAP_%s_cmap_%d,\t/* Canonically sorted */\n",
			MKID(expr), expr->_type_unique_index);
		else OUT("0,\n");
		if(C99_MODE) OUT(".ext_start = ");
		OUT("%d\t/* Extensions start */\n",
			compute_extensions_start(expr));
	);
	OUT("};\n");

	/*
	 * Emit asn_DEF_xxx table.
	 */
	emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
			ETD_HAS_SPECIFICS);

	REDIR(saved_target);

	if (tag2el) free(tag2el);

	return 0;
} /* _CHOICE_def() */

int
asn1c_lang_C_type_REFERENCE(arg_t *arg) {
	asn1p_ref_t *ref;

	ref = arg->expr->reference;
	if(ref->components[ref->comp_count-1].name[0] == '&') {
		asn1p_expr_t *extract;
		arg_t tmp;
		int ret;

		extract = asn1f_class_access_ex(arg->asn, arg->expr->module,
			arg->expr, arg->expr->rhs_pspecs, ref);
		if(extract == NULL)
			return -1;

		extract = asn1p_expr_clone(extract, 0);
		if(extract) {
			free(extract->Identifier);
			extract->Identifier = strdup(arg->expr->Identifier);
			if(extract->Identifier == NULL) {
				asn1p_expr_free(extract);
				return -1;
			}
		} else {
			return -1;
		}

		tmp = *arg;
		tmp.asn = arg->asn;
		tmp.expr = extract;

		ret = arg->default_cb(&tmp, NULL);

		asn1p_expr_free(extract);

		return ret;
	}


	return asn1c_lang_C_type_SIMPLE_TYPE(arg);
}

int
asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	int tags_count;
	int all_tags_count;
	enum tvm_compat tv_mode;
	enum etd_spec etd_spec;
	char *p;
	int saved_target = arg->target->target;

	if(arg->embed) {
		enum tnfmt tnfmt = TNF_CTYPE;

		/*
		 * If this is an optional compound type,
		 * refer it using "struct X" convention,
		 * as it may recursively include the current structure.
		 */
		if(expr->marker.flags & (EM_INDIRECT | EM_UNRECURSE)) {
			if(terminal_structable(arg, expr)) {
				tnfmt = TNF_RSAFE;
				if(saved_target != OT_FWD_DECLS) {
					REDIR(OT_FWD_DECLS);
					OUT("%s;\n",
						asn1c_type_name(arg, arg->expr, tnfmt));
				}
				REDIR(saved_target);
			}
		}


		OUT("%s", asn1c_type_name(arg, arg->expr, tnfmt));
		if(!expr->_anonymous_type) {
			OUT("%s", (expr->marker.flags&EM_INDIRECT)?"\t*":"\t ");
			OUT("%s", MKID_safe(expr));
			if((expr->marker.flags & (EM_DEFAULT & ~EM_INDIRECT))
					== (EM_DEFAULT & ~EM_INDIRECT))
				OUT("\t/* DEFAULT %s */",
					asn1f_printable_value(
						expr->marker.default_value));
			else if((expr->marker.flags & EM_OPTIONAL)
					== EM_OPTIONAL)
				OUT("\t/* OPTIONAL */");
		}

	} else {
		GEN_INCLUDE(asn1c_type_name(arg, expr, TNF_INCLUDE));

		REDIR(OT_TYPE_DECLS);

		OUT("typedef %s\t",
			asn1c_type_name(arg, arg->expr, TNF_CTYPE));
		OUT("%s%s_t",
			(expr->marker.flags & EM_INDIRECT)?"*":" ",
			MKID(expr));
	}

	if((expr->expr_type == ASN_BASIC_ENUMERATED)
	|| (0 /* -- prohibited by X.693:8.3.4 */
		&& expr->expr_type == ASN_BASIC_INTEGER
		&& expr_elements_count(arg, expr))
	|| (expr->expr_type == ASN_BASIC_INTEGER
		&& asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN)
	)
		etd_spec = ETD_HAS_SPECIFICS;
	else
		etd_spec = ETD_NO_SPECIFICS;

	/*
	 * If this type just blindly refers the other type, alias it.
	 * 	Type1 ::= Type2
	 */
	if(arg->embed && etd_spec == ETD_NO_SPECIFICS) {
		REDIR(saved_target);
		return 0;
	}
	if((!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS))
	&& (arg->embed || expr->tag.tag_class == TC_NOCLASS)
	&& etd_spec == ETD_NO_SPECIFICS
	&& 0	/* This shortcut is incompatible with XER */
	) {
		char *type_name;
		REDIR(OT_FUNC_DECLS);
		type_name = asn1c_type_name(arg, expr, TNF_SAFE);
		OUT("/* This type is equivalent to %s */\n", type_name);
		if(HIDE_INNER_DEFS) OUT("/* ");
		OUT("#define\tasn_DEF_%s\t", MKID(expr));
		type_name = asn1c_type_name(arg, expr, TNF_SAFE);
		OUT("asn_DEF_%s", type_name);
		if(HIDE_INNER_DEFS)
			OUT("\t// (Use -fall-defs-global to expose) */");
		OUT("\n");
		REDIR(OT_CODE);
		OUT("/* This type is equivalent to %s */\n", type_name);
		OUT("\n");
		REDIR(saved_target);
		return 0;
	}

	REDIR(OT_CODE);

	/*
	 * Constraint checking.
	 */
	if(!(arg->flags & A1C_NO_CONSTRAINTS) && expr->combined_constraints) {
		p = MKID(expr);
		if(HIDE_INNER_DEFS) OUT("static ");
		OUT("int\n");
		OUT("%s", p);
		if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
		OUT("_constraint(asn_TYPE_descriptor_t *td, const void *sptr,\n");
		INDENT(+1);
		OUT("\t\tasn_app_constraint_failed_f *ctfailcb, void *app_key) {");
		OUT("\n");
		DEBUG("expr constraint checking code for %s", p);
		if(asn1c_emit_constraint_checking_code(arg) == 1) {
			OUT("/* Replace with underlying type checker */\n");
			OUT("td->check_constraints "
				"= asn_DEF_%s.check_constraints;\n",
				asn1c_type_name(arg, expr, TNF_SAFE));
			OUT("return td->check_constraints"
				"(td, sptr, ctfailcb, app_key);\n");
		}
		INDENT(-1);
		OUT("}\n");
		OUT("\n");
	}

	REDIR(OT_STAT_DEFS);

	/*
	 * Print out asn_DEF_<type>_[all_]tags[] vectors.
	 */
	tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);
	DEBUG("emit tag vectors for %s %d, %d, %d", expr->Identifier,
		tv_mode, tags_count, all_tags_count);

	emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count,
		0, etd_spec);

	REDIR(OT_CODE);

	/*
	 * Emit suicidal functions.
	 */

	/*
	 * This function replaces certain fields from the definition
	 * of a type with the corresponding fields from the basic type
	 * (from which the current type is inherited).
	 */
	OUT("/*\n");
	OUT(" * This type is implemented using %s,\n",
		asn1c_type_name(arg, expr, TNF_SAFE));
	OUT(" * so here we adjust the DEF accordingly.\n");
	OUT(" */\n");

#if 0 /* remove unnecessary functions */
	OUT("static void\n");
	OUT("%s_%d_inherit_TYPE_descriptor(asn_TYPE_descriptor_t *td) {\n",
		MKID(expr), expr->_type_unique_index);
	INDENT(+1);
  {
	asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
	char *type_name = asn1c_type_name(arg, expr, TNF_SAFE);
	OUT("td->free_struct    = asn_DEF_%s.free_struct;\n",    type_name);
	OUT("td->print_struct   = asn_DEF_%s.print_struct;\n",   type_name);
	OUT("td->check_constraints = asn_DEF_%s.check_constraints;\n", type_name);
	OUT("td->ber_decoder    = asn_DEF_%s.ber_decoder;\n",    type_name);
	OUT("td->der_encoder    = asn_DEF_%s.der_encoder;\n",    type_name);
	OUT("td->xer_decoder    = asn_DEF_%s.xer_decoder;\n",    type_name);
	OUT("td->xer_encoder    = asn_DEF_%s.xer_encoder;\n",    type_name);
	OUT("td->uper_decoder   = asn_DEF_%s.uper_decoder;\n",   type_name);
	OUT("td->uper_encoder   = asn_DEF_%s.uper_encoder;\n",   type_name);
	OUT("td->oer_decoder    = asn_DEF_%s.oer_decoder;\n",   type_name);
	OUT("td->oer_encoder    = asn_DEF_%s.oer_encoder;\n",   type_name);
	if(!terminal && !tags_count) {
	  OUT("/* The next four lines are here because of -fknown-extern-type */\n");
	  OUT("td->tags           = asn_DEF_%s.tags;\n",         type_name);
	  OUT("td->tags_count     = asn_DEF_%s.tags_count;\n",   type_name);
	  OUT("td->all_tags       = asn_DEF_%s.all_tags;\n",     type_name);
	  OUT("td->all_tags_count = asn_DEF_%s.all_tags_count;\n",type_name);
	  OUT("/* End of these lines */\n");
	}
	OUT("if(!td->oer_constraints)\n");
		OUT("\ttd->oer_constraints = asn_DEF_%s.oer_constraints;\n",
			type_name);
	OUT("if(!td->per_constraints)\n");
		OUT("\ttd->per_constraints = asn_DEF_%s.per_constraints;\n",
			type_name);
	OUT("td->elements       = asn_DEF_%s.elements;\n",       type_name);
	OUT("td->elements_count = asn_DEF_%s.elements_count;\n", type_name);
	if(etd_spec != ETD_NO_SPECIFICS) {
		INDENT(-1);
		OUT("     /* ");
	}
	OUT("td->specifics      = asn_DEF_%s.specifics;",        type_name);
	if(etd_spec == ETD_NO_SPECIFICS) {
		INDENT(-1);
		OUT("\n");
	} else {
		OUT("\t// Defined explicitly */\n");
	}
  }
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("void\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_free(asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tvoid *struct_ptr, int contents_only) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("td->free_struct(td, struct_ptr, contents_only);\n");
	);
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("int\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_print(asn_TYPE_descriptor_t *td, const void *struct_ptr,\n");
	INDENTED(
	OUT("\tint ilevel, asn_app_consume_bytes_f *cb, void *app_key) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->print_struct(td, struct_ptr, ilevel, cb, app_key);\n");
	);
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_dec_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tvoid **structure, const void *bufptr, size_t size, int tag_mode) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->ber_decoder(opt_codec_ctx, td, structure, bufptr, size, tag_mode);\n");
	);
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_enc_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_encode_der(asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tvoid *structure, int tag_mode, ber_tlv_tag_t tag,\n");
	OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->der_encoder(td, structure, tag_mode, tag, cb, app_key);\n");
	);
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_dec_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_decode_xer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tvoid **structure, const char *opt_mname, const void *bufptr, size_t size) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->xer_decoder(opt_codec_ctx, td, structure, opt_mname, bufptr, size);\n");
	);
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_enc_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_encode_xer(asn_TYPE_descriptor_t *td, void *structure,\n");
	INDENTED(
	OUT("\tint ilevel, enum xer_encoder_flags_e flags,\n");
	OUT("\tasn_app_consume_bytes_f *cb, void *app_key) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->xer_encoder(td, structure, ilevel, flags, cb, app_key);\n");
	);
	OUT("}\n");
	OUT("\n");

  if(arg->flags & A1C_GEN_OER) {
	p = MKID(expr);

	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_dec_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tasn_oer_constraints_t *constraints, void **structure, const void *buffer, size_t size) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->oer_decoder(opt_codec_ctx, td, constraints, structure, buffer, size);\n");
	);
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_enc_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_encode_oer(asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tasn_oer_constraints_t *constraints,\n");
	OUT("\tvoid *structure, asn_app_consume_bytes_f *cb, void *app_key) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->uper_encoder(td, constraints, structure, cb, app_key);\n");
	);
	OUT("}\n");
	OUT("\n");
  }

  if(arg->flags & A1C_GEN_PER) {
	p = MKID(expr);

	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_dec_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_decode_uper(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tasn_per_constraints_t *constraints, void **structure, asn_per_data_t *per_data) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->uper_decoder(opt_codec_ctx, td, constraints, structure, per_data);\n");
	);
	OUT("}\n");
	OUT("\n");

	p = MKID(expr);
	if(HIDE_INNER_DEFS) OUT("static ");
	OUT("asn_enc_rval_t\n");
	OUT("%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT("_encode_uper(asn_TYPE_descriptor_t *td,\n");
	INDENTED(
	OUT("\tasn_per_constraints_t *constraints,\n");
	OUT("\tvoid *structure, asn_per_outp_t *per_out) {\n");
	OUT("%s_%d_inherit_TYPE_descriptor(td);\n",
		p, expr->_type_unique_index);
	OUT("return td->uper_encoder(td, constraints, structure, per_out);\n");
	);
	OUT("}\n");
	OUT("\n");
  }
#endif
	REDIR(OT_FUNC_DECLS);

	p = MKID(expr);
	if(HIDE_INNER_DEFS) {
		OUT("/* extern asn_TYPE_descriptor_t asn_DEF_%s_%d;"
			"\t// (Use -fall-defs-global to expose) */\n",
			p, expr->_type_unique_index);
	} else {
		OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;\n", p);
		if (etd_spec == ETD_HAS_SPECIFICS) {
			if((expr->expr_type == ASN_BASIC_ENUMERATED) ||
				(expr->expr_type == ASN_BASIC_INTEGER)) {
				if(expr->_type_referenced) {
					OUT("extern asn_INTEGER_specifics_t "
						"asn_SPC_%s_specs_%d;\n", p, expr->_type_unique_index);
				}
			} else {
				asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);

				OUT("extern asn_%s_specifics_t ", asn1c_type_name(arg, terminal, TNF_SAFE));
				OUT("asn_SPC_%s_specs_%d;\n", MKID(expr), expr->_type_unique_index);
			}
		}
		OUT("asn_struct_free_f %s_free;\n", p);
		OUT("asn_struct_print_f %s_print;\n", p);
		OUT("asn_constr_check_f %s_constraint;\n", p);
		OUT("ber_type_decoder_f %s_decode_ber;\n", p);
		OUT("der_type_encoder_f %s_encode_der;\n", p);
		OUT("xer_type_decoder_f %s_decode_xer;\n", p);
		OUT("xer_type_encoder_f %s_encode_xer;\n", p);
		if(arg->flags & A1C_GEN_OER) {
		OUT("oer_type_decoder_f %s_decode_oer;\n", p);
		OUT("oer_type_encoder_f %s_encode_oer;\n", p);
		}
		if(arg->flags & A1C_GEN_PER) {
		OUT("per_type_decoder_f %s_decode_uper;\n", p);
		OUT("per_type_encoder_f %s_encode_uper;\n", p);
		}
	}

	REDIR(saved_target);

	return 0;
}

int
asn1c_lang_C_type_EXTENSIBLE(arg_t *arg) {

	OUT("/*\n");
	OUT(" * This type is extensible,\n");
	OUT(" * possible extensions are below.\n");
	OUT(" */\n");

	return 0;
}

static int
compute_extensions_start(asn1p_expr_t *expr) {
	asn1p_expr_t *v;
	int eidx = 0;
	TQ_FOR(v, &(expr->members), next) {
		if(v->expr_type == A1TC_EXTENSIBLE)
			return eidx;
		eidx++;
	}
	return -1;
}

static int
_print_tag(arg_t *arg, struct asn1p_type_tag_s *tag) {

	OUT("(");
	switch(tag->tag_class) {
	case TC_UNIVERSAL:		OUT("ASN_TAG_CLASS_UNIVERSAL"); break;
	case TC_APPLICATION:		OUT("ASN_TAG_CLASS_APPLICATION"); break;
	case TC_CONTEXT_SPECIFIC:	OUT("ASN_TAG_CLASS_CONTEXT"); break;
	case TC_PRIVATE:		OUT("ASN_TAG_CLASS_PRIVATE"); break;
	case TC_NOCLASS:
		break;
	}
	OUT(" | (%s << 2))", asn1p_itoa(tag->tag_value));

	return 0;
}


static int
_tag2el_cmp(const void *ap, const void *bp) {
	const tag2el_t *a = ap;
	const tag2el_t *b = bp;
	const struct asn1p_type_tag_s *ta = &a->el_tag;
	const struct asn1p_type_tag_s *tb = &b->el_tag;

	if(ta->tag_class == tb->tag_class) {
		if(ta->tag_value == tb->tag_value) {
			/*
			 * Sort by their respective positions.
			 */
			if(a->el_no < b->el_no)
				return -1;
			else if(a->el_no > b->el_no)
				return 1;
			return 0;
		} else if(ta->tag_value < tb->tag_value)
			return -1;
		else
			return 1;
	} else if(ta->tag_class < tb->tag_class) {
		return -1;
	} else {
		return 1;
	}
}

/*
 * For constructed types, number of external tags may be greater than
 * number of elements in the type because of CHOICE type.
 * T ::= SET {		-- Three possible tags:
 *     a INTEGER,	-- One tag is here...
 *     b Choice1	-- ... and two more tags are there.
 * }
 * Choice1 ::= CHOICE {
 *     s1 IA5String,
 *     s2 ObjectDescriptor
 * }
 */
static int
_fill_tag2el_map(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags) {
	asn1p_expr_t *expr = arg->expr;
	arg_t tmparg = *arg;
	asn1p_expr_t *v;
	int element = 0;
	int original_count = *count;
	int sort_until = -1;

	TQ_FOR(v, &(expr->members), next) {
		if(v->expr_type == A1TC_EXTENSIBLE) {
			/*
			 * CXER mandates sorting
			 * only for the root part.
			 */
			if(flags == FTE_CANONICAL_XER
			&& sort_until == -1)
				sort_until = *count;
			continue;
		}

		tmparg.expr = v;

		if(_add_tag2el_member(&tmparg, tag2el, count,
				(el_no==-1)?element:el_no, flags)) {
			return -1;
		}

		element++;
	}


	if(flags == FTE_CANONICAL_XER) {
		if(sort_until == -1) sort_until = *count;
		qsort((*tag2el) + original_count,
			sort_until - original_count,
				sizeof(**tag2el), _tag2el_cmp);
		if(arg->expr->expr_type == ASN_CONSTR_CHOICE
		&& (sort_until - original_count) >= 1) {
			/* Only take in account the root component */
			*count = original_count + 1;
		}
	} else {
		/*
		 * Sort the map according to canonical order of their
		 * tags and element numbers.
		 */
		qsort(*tag2el, *count, sizeof(**tag2el), _tag2el_cmp);
	}

	/*
	 * Initialize .toff_{first|last} members.
	 */
	if(*count) {
		struct asn1p_type_tag_s *cur_tag = 0;
		tag2el_t *cur = *tag2el;
		tag2el_t *end = cur + *count;
		int occur, i;
		for(occur = 0; cur < end; cur++) {
			if(cur_tag == 0
			|| cur_tag->tag_value != cur->el_tag.tag_value
			|| cur_tag->tag_class != cur->el_tag.tag_class) {
				cur_tag = &cur->el_tag;
				occur = 0;
			} else {
				occur++;
			}
			cur->toff_first = -occur;
			for(i = 0; i >= -occur; i--)
				cur[i].toff_last = -i;
		}
	}

	return 0;
}

static int
_add_tag2el_member(arg_t *arg, tag2el_t **tag2el, int *count, int el_no, fte_e flags) {
	struct asn1p_type_tag_s tag;
	int ret;

	assert(el_no >= 0);

	ret = asn1f_fetch_outmost_tag(arg->asn, arg->expr->module,
			arg->expr, &tag, AFT_IMAGINARY_ANY);
	if(ret == 0) {
		tag2el_t *te;
		int new_count = (*count) + 1;
		void *p;

		if(tag.tag_value == -1) {
			/*
			 * This is an untagged ANY type,
			 * proceed without adding a tag
			 */
			return 0;
		}

		p = realloc(*tag2el, new_count * sizeof(tag2el_t));
		if(p)	*tag2el = p;
		else	return -1;

		if(0) DEBUG("Found tag for %s: %ld",
			arg->expr->Identifier,
			(long)tag.tag_value);

		te = &((*tag2el)[*count]);
		te->el_tag = tag;
		te->el_no = el_no;
		te->from_expr = arg->expr;
		*count = new_count;
		return 0;
	}

	DEBUG("Searching tag in complex expression %s:%x at line %d",
		arg->expr->Identifier,
		arg->expr->expr_type,
		arg->expr->_lineno);

	/*
	 * Iterate over members of CHOICE type.
	 */
	if(arg->expr->expr_type == ASN_CONSTR_CHOICE) {
		return _fill_tag2el_map(arg, tag2el, count, el_no, flags);
	}

	if(arg->expr->expr_type == A1TC_REFERENCE) {
		arg_t tmp = *arg;
		asn1p_expr_t *expr;
		expr = asn1f_lookup_symbol_ex(tmp.asn, tmp.expr,
			arg->expr->reference);
		if(expr) {
			tmp.expr = expr;
			return _add_tag2el_member(&tmp, tag2el, count, el_no, flags);
		} else {
			FATAL("Cannot dereference %s at line %d",
				arg->expr->Identifier,
				arg->expr->_lineno);
			return -1;
		}
	}

	DEBUG("No tag for %s at line %d",
		arg->expr->Identifier,
		arg->expr->_lineno);

	return -1;
}

static int
emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier) {
	asn1p_expr_t *expr = arg->expr;
	int i;

	if(!tag2el_count) return 0;	/* No top level tags */

	OUT("static const asn_TYPE_tag2member_t asn_MAP_%s_tag2el%s_%d[] = {\n",
		MKID(expr), opt_modifier?opt_modifier:"",
		expr->_type_unique_index);
	for(i = 0; i < tag2el_count; i++) {
		OUT("    { ");
		_print_tag(arg, &tag2el[i].el_tag);
		OUT(", ");
		OUT("%d, ", tag2el[i].el_no);
		OUT("%d, ", tag2el[i].toff_first);
		OUT("%d ", tag2el[i].toff_last);
		OUT("}%s /* %s",
			(i + 1 < tag2el_count) ? "," : "",
			tag2el[i].from_expr->Identifier);
        if(arg->flags & A1C_LINE_REFS)
            OUT("at %d", tag2el[i].from_expr->_lineno);
        OUT(" */\n");
	}
	OUT("};\n");

	return 0;
}

static enum tvm_compat
emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tags_count_r, int *all_tags_count_r) {
	struct asn1p_type_tag_s *tags = 0;	/* Effective tags */
	struct asn1p_type_tag_s *all_tags = 0;	/* The full array */
	int tags_count = 0;
	int all_tags_count = 0;
	enum tvm_compat tv_mode = _TVM_SAME;
	int i;

	/* Cleanup before proceeding. */
	*tags_count_r = 0;
	*all_tags_count_r = 0;

	/* Fetch a chain of tags */
	tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr, &tags, 0);
	if(tags_count < 0) {
		DEBUG("fail to fetch tags for %s", expr->Identifier);
		return -1;
	}

	/* Fetch a chain of tags */
	all_tags_count = asn1f_fetch_tags(arg->asn, expr->module, expr,
		&all_tags, AFT_FULL_COLLECT);
	if(all_tags_count < 0) {
		free(tags);
		DEBUG("fail to fetch tags chain for %s", expr->Identifier);
		return -1;
	}

	assert(tags_count <= all_tags_count);
	assert((tags_count?0:1) == (all_tags_count?0:1));

	if(tags_count <= all_tags_count) {
		for(i = 0; i < tags_count; i++) {
			if(tags[i].tag_value != all_tags[i].tag_value
			|| tags[i].tag_class != all_tags[i].tag_class) {
				tv_mode = _TVM_DIFFERENT;
				break;
			}
		}
		if(i == tags_count && tags_count < all_tags_count)
			tv_mode = _TVM_SUBSET;
	} else {
		tv_mode = _TVM_DIFFERENT;
	}

#define	EMIT_TAGS_TABLE(name, tags, tags_count)	do {			\
		OUT("static const ber_tlv_tag_t asn_DEF_%s%s_tags_%d[] = {\n",\
			MKID(expr), name,			\
			expr->_type_unique_index);			\
		INDENT(+1);						\
		/* Print the array of collected tags */			\
		for(i = 0; i < tags_count; i++) {			\
			if(i) OUT(",\n");				\
			_print_tag(arg, &tags[i]);			\
		}							\
		OUT("\n");						\
		INDENT(-1);						\
		OUT("};\n");						\
	} while(0)

	if(tags_count) {
		if(tv_mode == _TVM_SUBSET)
			EMIT_TAGS_TABLE("", all_tags, all_tags_count);
		else
			EMIT_TAGS_TABLE("", tags, tags_count);
	}

	if(all_tags_count) {
		if(tv_mode == _TVM_DIFFERENT)
			EMIT_TAGS_TABLE("_all", all_tags, all_tags_count);
	}

	free(tags);
	free(all_tags);

	*tags_count_r = tags_count;
	*all_tags_count_r = all_tags_count;

	return tv_mode;
}

static int
expr_elements_count(arg_t *arg, asn1p_expr_t *expr) {
	asn1p_expr_t *topmost_parent;
	asn1p_expr_t *v;
	int elements = 0;

	topmost_parent = asn1f_find_terminal_type_ex(arg->asn, expr);
	if(!topmost_parent) return 0;

	if(!(topmost_parent->expr_type & ASN_CONSTR_MASK)
	&& !(topmost_parent->expr_type == ASN_BASIC_INTEGER)
	&& !(topmost_parent->expr_type == ASN_BASIC_ENUMERATED)
	&& !(topmost_parent->expr_type == ASN_BASIC_BIT_STRING))
		return 0;

	TQ_FOR(v, &(topmost_parent->members), next) {
		if(v->expr_type != A1TC_EXTENSIBLE)
			elements++;
	}

	return elements;
}

static asn1p_expr_type_e
expr_get_type(arg_t *arg, asn1p_expr_t *expr) {
	asn1p_expr_t *terminal;
	terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
	if(terminal) return terminal->expr_type;
	return A1TC_INVALID;
}

static asn1c_integer_t
PER_FROM_alphabet_characters(asn1cnst_range_t *range) {
	asn1c_integer_t numchars = 0;
	if(range->el_count) {
		int i;
		for(i = 0; i < range->el_count; i++)
			numchars
			+= PER_FROM_alphabet_characters(range->elements[i]);
	} else {
		assert(range->left.type == ARE_VALUE);
		assert(range->right.type == ARE_VALUE);
		numchars = 1 + (range->right.value - range->left.value);
	}
	return numchars;
}

static void
emit_single_member_OER_constraint_comment(arg_t *arg, asn1cnst_range_t *range, char *type) {

	/*
	 * Print some courtesy debug information.
	 */
    if(range
       && (range->left.type == ARE_VALUE || range->right.type == ARE_VALUE)) {
        OUT("\t/* ");
		if(type) OUT("(%s", type);
		OUT("(");
		if(range->left.type == ARE_VALUE)
			OUT("%s", asn1p_itoa(range->left.value));
		else
			OUT("MIN");
		OUT("..");
		if(range->right.type == ARE_VALUE)
			OUT("%s", asn1p_itoa(range->right.value));
		else
			OUT("MAX");
		if(range->extensible) OUT(",...");
		if(type) OUT(")");
		OUT(") */");
	}
}

static int
emit_single_member_OER_constraint_value(arg_t *arg, asn1cnst_range_t *range) {
    if(!range) {
        /* oer_support.h: asn_oer_constraint_s */
        OUT("{ 0, 0 }");
        return 0;
    }

	if(range->incompatible || range->not_OER_visible) {
		OUT("{ 0, 0 }");
	} else if(range->left.type == ARE_VALUE &&
            range->right.type == ARE_VALUE) {
        asn1c_integer_t lb = range->left.value;
        asn1c_integer_t ub = range->right.value;
        unsigned width = 0;
        unsigned positive = 0;


        if(lb >= 0) {
            /* X.969 08/2015 10.2(a) */
            if(ub <= 255) {
                width = 1;
            } else if(ub <= 65535) {
                width = 2;
            } else if((unsigned long long)ub <= 4294967295UL) {
                width = 4;
            } else if((unsigned long long)ub <= 18446744073709551615ULL) {
                width = 8;
            }
            positive = 1;
        } else {
            positive = 0;
            /* X.969 08/2015 10.2(b) - no lower bound or negative lower bound */
            if(lb >= -128 && ub <= 127) {
                width = 1;
            } else if(lb >= -32768 && ub <= 32767) {
                width = 2;
            } else if(lb >= -2147483648L && ub <= 2147483647L) {
                width = 4;
            } else if(lb >= (-9223372036854775807LL-1)
                      && ub <= 9223372036854775807LL) {
                width = 8;
            }
        }
        OUT("{ %u, %u }", width, positive);
    } else {
        OUT("{ 0, 0 }");
    }

    return 0;
}

static int
emit_single_member_OER_constraint_size(arg_t *arg, asn1cnst_range_t *range) {
    if(!range) {
        /* oer_support.h: asn_oer_constraint_s */
		OUT("-1");
		return 0;
    }

    if(range->incompatible || range->not_OER_visible) {
        OUT("-1");
    } else {
        if(range->left.type == ARE_VALUE && range->right.type == ARE_VALUE
           && range->left.value == range->right.value
           && range->left.value >= 0) {
            OUT("%s", asn1p_itoa(range->left.value));
        } else {
            OUT("-1");
        }
    }

	return 0;
}

static int
emit_single_member_PER_constraint(arg_t *arg, asn1cnst_range_t *range, int alphabetsize, const char *type) {
    if(!range || range->incompatible || range->not_PER_visible) {
        OUT("{ APC_UNCONSTRAINED,\t-1, -1,  0,  0 }");
		return 0;
    }

    if(range->left.type == ARE_VALUE) {
		if(range->right.type == ARE_VALUE) {
			asn1c_integer_t cover = 1;
			asn1c_integer_t r = 1 + range->right.value
					      - range->left.value;
			size_t rbits;	/* Value range bits */
			ssize_t ebits;	/* Value effective range bits */

			if(range->empty_constraint)
				r = 0;

			if(alphabetsize) {
				/* X.691: 27.5.2 */
				r = PER_FROM_alphabet_characters(range);
			}

			/* Compute real constraint */
			for(rbits = 0; rbits < (8 * sizeof(r)); rbits++) {
				if(r <= cover)
					break;
				cover *= 2;	/* Can't do shifting */
				if(cover < 0) {
					FATAL("Constraint at line %d too wide "
						"for %d-bits integer type",
						arg->expr->_lineno,
						sizeof(r) * 8);
					rbits = sizeof(r);
					break;
				}
			}

			if(alphabetsize) {
				ebits = rbits;
			} else {
				/* X.691, #10.9.4.1 */
				for(ebits = 0; ebits <= 16; ebits++)
					if(r <= 1 << ebits) break;
				if(ebits == 17
				|| range->right.value >= 65536)
					ebits = -1;
			if(0) {
				/* X.691, #10.5.7.1 */
				for(ebits = 0; ebits <= 8; ebits++)
					if(r <= 1 << ebits) break;
				if(ebits == 9) {
					if(r <= 65536)
						ebits = 16;
					else
						ebits = -1;
				}
			}
			}

			OUT("{ APC_CONSTRAINED%s,%s% d, % d, ",
				range->extensible
					? " | APC_EXTENSIBLE" : "",
				range->extensible ? " " : "\t", rbits, ebits);

			if(alphabetsize) {
				asn1c_integer_t lv = range->left.value;
				asn1c_integer_t rv = range->right.value;
				int gcmt = 0;
				if(lv > 0x7fffffff) { lv = 0x7fffffff; gcmt++; }
				if(rv > 0x7fffffff) { rv = 0x7fffffff; gcmt++; }
				if(gcmt) {
					OINTS(lv); OUT(", "); OINTS(rv); OUT(" }");
					goto pcmt;
				}
			}
		} else {
			if(range->extensible) {
				OUT("{ APC_SEMI_CONSTRAINED | APC_EXTENSIBLE, "
					"-1, ");
			} else {
				OUT("{ APC_SEMI_CONSTRAINED,\t-1, -1, ");
			}
		}
		OINTS(range->left.value); OUT(", ");
		OINTS(range->right.value); OUT(" }");
	} else {
		OUT("{ APC_UNCONSTRAINED,\t-1, -1,  0,  0 }");
	}

  pcmt:

	/*
	 * Print some courtesy debug information.
	 */
	if(range->left.type == ARE_VALUE
	|| range->right.type == ARE_VALUE) {
		OUT("\t/* ");
		if(type) OUT("(%s", type);
		OUT("(");
		if(range->left.type == ARE_VALUE)
			OUT("%s", asn1p_itoa(range->left.value));
		else
			OUT("MIN");
		OUT("..");
		if(range->right.type == ARE_VALUE)
			OUT("%s", asn1p_itoa(range->right.value));
		else
			OUT("MAX");
		if(range->extensible) OUT(",...");
		if(type) OUT(")");
		OUT(") */");
	}

	return 0;
}

static int
emit_member_OER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
    int save_target = arg->target->target;
    asn1cnst_range_t *range;
	asn1p_expr_type_e etype;

    etype = expr_get_type(arg, expr);

    if((arg->flags & A1C_GEN_OER)
       && (expr->constraints || etype == ASN_BASIC_ENUMERATED
           || etype == ASN_CONSTR_CHOICE)) {
        /* Fall through */
    } else {
        return 0;
    }

    REDIR(OT_CTDEFS);

    OUT("static asn_oer_constraints_t "
        "asn_OER_%s_%s_constr_%d GCC_NOTUSED = {\n",
        pfx, MKID(expr), expr->_type_unique_index);

    INDENT(+1);

    /* .value{.width,.positive} */
    range = asn1constraint_compute_OER_range(expr->Identifier, etype,
                                             expr->combined_constraints,
                                             ACT_EL_RANGE, 0, 0, 0);
    if(emit_single_member_OER_constraint_value(arg, range)) {
        return -1;
    }
    emit_single_member_OER_constraint_comment(arg, range, 0);
    asn1constraint_range_free(range);

	OUT(",\n");

    /* .size */
    range = asn1constraint_compute_OER_range(expr->Identifier, etype,
                                             expr->combined_constraints,
                                             ACT_CT_SIZE, 0, 0, 0);
    if(emit_single_member_OER_constraint_size(arg, range)) {
        return -1;
    }
    emit_single_member_OER_constraint_comment(arg, range, "SIZE");
    asn1constraint_range_free(range);

    INDENT(-1);

    OUT("};\n");

    REDIR(save_target);

    return 0;
}

static int
emit_member_PER_constraints(arg_t *arg, asn1p_expr_t *expr, const char *pfx) {
	int save_target = arg->target->target;
	asn1cnst_range_t *range;
	asn1p_expr_type_e etype;

	etype = expr_get_type(arg, expr);

	if((arg->flags & A1C_GEN_PER)
	&& (expr->constraints
		|| etype == ASN_BASIC_ENUMERATED
		|| etype == ASN_CONSTR_CHOICE)
	) {
		/* Fall through */
	} else {
		return 0;
	}

	if(expr->_type_referenced) {
		REDIR(OT_FUNC_DECLS);

		OUT("extern asn_per_constraints_t "
			"asn_PER_%s_%s_constr_%d;\n",
			pfx, MKID(expr), expr->_type_unique_index);
	}

	REDIR(OT_CTDEFS);

	if(!(expr->_type_referenced)) OUT("static ");
	OUT("asn_per_constraints_t "
		"asn_PER_%s_%s_constr_%d GCC_NOTUSED = {\n",
		pfx, MKID(expr), expr->_type_unique_index);

	INDENT(+1);

	/*
	 * ENUMERATED and CHOICE are special.
	 */
	if(etype == ASN_BASIC_ENUMERATED
	|| etype == ASN_CONSTR_CHOICE) {
		asn1cnst_range_t tmprng;
		asn1p_expr_t *v;
		int extensible = 0;
		int eidx = -1;

		expr = asn1f_find_terminal_type_ex(arg->asn, expr);
		assert(expr);

		TQ_FOR(v, &(expr->members), next) {
			if(v->expr_type == A1TC_EXTENSIBLE) {
				extensible++;
				break;
			}
			eidx++;
		}

		memset(&tmprng, 0, sizeof (tmprng));
		tmprng.extensible = extensible;
		if(eidx < 0) tmprng.empty_constraint = 1;
		tmprng.left.type = ARE_VALUE;
		tmprng.left.value = 0;
		tmprng.right.type = ARE_VALUE;
		tmprng.right.value = eidx < 0 ? 0 : eidx;
		if(emit_single_member_PER_constraint(arg, &tmprng, 0, 0))
			return -1;
	} else if(etype & ASN_STRING_KM_MASK) {
		range = asn1constraint_compute_PER_range(expr->Identifier, etype,
				expr->combined_constraints, ACT_CT_FROM,
				0, 0, 0);
		DEBUG("Emitting FROM constraint for %s", expr->Identifier);

		if((range->left.type == ARE_MIN && range->right.type == ARE_MAX)
		|| range->not_PER_visible) {
			switch(etype) {
			case ASN_STRING_BMPString:
				range->left.type = ARE_VALUE;
				range->left.value = 0;
				range->right.type = ARE_VALUE;
				range->right.value = 65535;
				range->not_PER_visible = 0;
				range->extensible = 0;
				break;
			case ASN_STRING_UniversalString:
				OUT("{ APC_CONSTRAINED,\t32, 32,"
					" 0, 2147483647 }"
					" /* special case 1 */\n");
				goto avoid;
			default:
				break;
			}
		}
		if(emit_single_member_PER_constraint(arg, range, 1, 0))
			return -1;
		avoid:
		asn1constraint_range_free(range);
	} else {
		range = asn1constraint_compute_PER_range(expr->Identifier, etype,
				expr->combined_constraints, ACT_EL_RANGE,
				0, 0, 0);
		if(emit_single_member_PER_constraint(arg, range, 0, 0))
			return -1;
		asn1constraint_range_free(range);
	}
	OUT(",\n");

	range = asn1constraint_compute_PER_range(expr->Identifier, etype,
			expr->combined_constraints, ACT_CT_SIZE, 0, 0, 0);
	if(emit_single_member_PER_constraint(arg, range, 0, "SIZE"))
		return -1;
	asn1constraint_range_free(range);
	OUT(",\n");

	if((etype & ASN_STRING_KM_MASK) && (expr->_mark & TM_PERFROMCT)) {
		int old_target = arg->target->target;
		REDIR(OT_CODE);

		OUT("static int asn_PER_MAP_%s_%d_v2c(unsigned int value) {\n",
			MKID(expr), expr->_type_unique_index);
		OUT("\tif(value >= sizeof(permitted_alphabet_table_%d)/"
			"sizeof(permitted_alphabet_table_%d[0]))\n",
			expr->_type_unique_index,
			expr->_type_unique_index);
		OUT("\t\treturn -1;\n");
		OUT("\treturn permitted_alphabet_table_%d[value] - 1;\n",
			expr->_type_unique_index);
		OUT("}\n");

		OUT("static int asn_PER_MAP_%s_%d_c2v(unsigned int code) {\n",
			MKID(expr), expr->_type_unique_index);
		OUT("\tif(code >= sizeof(permitted_alphabet_code2value_%d)/"
			"sizeof(permitted_alphabet_code2value_%d[0]))\n",
			expr->_type_unique_index,
			expr->_type_unique_index);
		OUT("\t\treturn -1;\n");
		OUT("\treturn permitted_alphabet_code2value_%d[code];\n",
			expr->_type_unique_index);
		OUT("}\n");

		REDIR(old_target);

		OUT("asn_PER_MAP_%s_%d_v2c,\t/* Value to PER code map */\n",
			MKID(expr), expr->_type_unique_index);
		OUT("asn_PER_MAP_%s_%d_c2v\t/* PER code to value map */\n",
			MKID(expr), expr->_type_unique_index);
	} else if(etype & ASN_STRING_KM_MASK) {
		DEBUG("No PER value map necessary for %s", MKID(expr));
		OUT("0, 0\t/* No PER character map necessary */\n");
	} else {
		OUT("0, 0\t/* No PER value map */\n");
	}

	INDENT(-1);

	OUT("};\n");

	REDIR(save_target);

	return 0;
}

static int
safe_string(const uint8_t *buf, int size) {
	const uint8_t *end = buf + size;
	for(; buf < end; buf++) {
		int ch = *buf;
		if((ch < 0x20 || ch > 0x7e) || ch == '"')
			return 0;
	}
	return 1;
}

static void
emit_default_value(arg_t *arg, asn1p_value_t *v) {

	OUT("static uint8_t defv[] = ");
	assert(v->type == ATV_STRING);

	if(safe_string(v->value.string.buf, v->value.string.size)) {
		OUT("\"%s\";\n", v->value.string.buf);
	} else {
		uint8_t *b = v->value.string.buf;
		uint8_t *e = v->value.string.size + b;
		OUT("{ ");
		for(;b < e; b++)
			OUT("0x%02x, ", *b);
		OUT("0 };\n");
	}
}

static int
try_inline_default(arg_t *arg, asn1p_expr_t *expr, int out) {
	int save_target = arg->target->target;
	asn1p_expr_type_e etype = expr_get_type(arg, expr);
	int fits_long = 0;

	switch(etype) {
	case ASN_BASIC_BOOLEAN:
		fits_long = 1;
	case ASN_BASIC_INTEGER:
	case ASN_BASIC_ENUMERATED:
		if(expr->marker.default_value == NULL
		|| expr->marker.default_value->type != ATV_INTEGER)
			break;
		if(!fits_long)
			fits_long = asn1c_type_fits_long(arg, expr)!=FL_NOTFIT;
		if(fits_long && !expr->marker.default_value->value.v_integer)
			expr->marker.flags &= ~EM_INDIRECT;
		if(!out) {
			OUT("asn_DFL_%d_set_%s,",
				expr->_type_unique_index,
				asn1p_itoa(expr->marker.default_value->value.v_integer));
            OUT("\t/* DEFAULT %s */\n",
				asn1p_itoa(expr->marker.default_value->value.v_integer));
			return 1;
		}
		REDIR(OT_STAT_DEFS);
		OUT("static int asn_DFL_%d_set_%s(int set_value, void **sptr) {\n",
			expr->_type_unique_index,
			asn1p_itoa(expr->marker.default_value->value.v_integer));
		INDENT(+1);
		OUT("%s *st = *sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
		OUT("\n");
		OUT("if(!st) {\n");
		OUT("\tif(!set_value) return -1;\t/* Not a default value */\n");
		OUT("\tst = (*sptr = CALLOC(1, sizeof(*st)));\n");
		OUT("\tif(!st) return -1;\n");
		OUT("}\n");
		OUT("\n");
		OUT("if(set_value) {\n");
		INDENT(+1);
		OUT("/* Install default value %s */\n",
			asn1p_itoa(expr->marker.default_value->value.v_integer));
		if(fits_long) {
			OUT("*st = ");
			OINT(expr->marker.default_value->value.v_integer);
			OUT(";\n");
			OUT("return 0;\n");
		} else {
			OUT("return asn_long2INTEGER(st, ");
			OINT(expr->marker.default_value->value.v_integer);
			OUT(");\n");
		}
		INDENT(-1);
		OUT("} else {\n");
		INDENT(+1);
		OUT("/* Test default value %s */\n",
			asn1p_itoa(expr->marker.default_value->value.v_integer));
		if(fits_long) {
			OUT("return (*st == %s);\n",
				asn1p_itoa(expr->marker.default_value->value.v_integer));
		} else {
			OUT("long value;\n");
			OUT("if(asn_INTEGER2long(st, &value))\n");
			OUT("\treturn -1;\n");
			OUT("return (value == %s);\n",
				asn1p_itoa(expr->marker.default_value->value.v_integer));
		}
		INDENT(-1);
		OUT("}\n");
		INDENT(-1);
		OUT("}\n");
		REDIR(save_target);
		return 1;
	case ASN_BASIC_NULL:
		//expr->marker.flags &= ~EM_INDIRECT;
		return 0;
	default:
	  if(etype & ASN_STRING_KM_MASK) {
		if(expr->marker.default_value == NULL
		|| expr->marker.default_value->type != ATV_STRING)
			break;
		if(!out) {
			OUT("asn_DFL_%d_set,\t/* DEFAULT \"%s\" */\n",
				expr->_type_unique_index,
				expr->marker.default_value->value.string.buf);
			return 1;
		}
		REDIR(OT_STAT_DEFS);
		OUT("static int asn_DFL_%d_set(int set_value, void **sptr) {\n", expr->_type_unique_index);
		INDENT(+1);
		emit_default_value(arg, expr->marker.default_value);
		OUT("%s *st = *sptr;\n", asn1c_type_name(arg, expr, TNF_CTYPE));
		OUT("\n");
		OUT("if(!st) {\n");
		OUT("\tif(!set_value) return -1;\t/* Not a default value */\n");
		OUT("\tst = (*sptr = CALLOC(1, sizeof(*st)));\n");
		OUT("\tif(!st) return -1;\n");
		OUT("}\n");
		OUT("\n");
		OUT("if(set_value) {\n");
		INDENT(+1);
			OUT("uint8_t *ptr = MALLOC(sizeof(defv));\n");
			OUT("if(!ptr) return -1;\n");
			OUT("memcpy(ptr, &defv, sizeof(defv));\n");
			OUT("FREEMEM(st->buf);\n");
			OUT("st->buf = ptr;\n");
			OUT("st->size = sizeof(defv) - 1;\n");
			OUT("return 0;\n");
		INDENT(-1);
		OUT("} else {\n");
		INDENT(+1);
			OUT("if(st->size != (sizeof(defv) - 1)\n");
			OUT("|| memcmp(st->buf, &defv, sizeof(defv) - 1))\n");
			OUT("\treturn 0;\n");
			OUT("return 1;\n");
		INDENT(-1);
		OUT("}\n"); OUT("\n");
		INDENT(-1);
		OUT("}\n");
		REDIR(save_target);
		return 1;
	  }
	  break;
	}
	return 0;
}

static int
emit_member_type_selector(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *opt_ioc) {
	int save_target = arg->target->target;
    asn1p_expr_t *parent_expr = arg->expr;

    const asn1p_constraint_t *crc =
        asn1p_get_component_relation_constraint(expr->combined_constraints);
    if(!crc || crc->el_count <= 1) {
        /* Not an Open Type, it seems. */
        OUT("0");
        return 0;
    }

    if(crc->el_count <= 1 || crc->elements[0]->type != ACT_EL_VALUE
       || crc->elements[0]->value->type != ATV_REFERENCED
       || crc->elements[0]->value->value.reference->comp_count != 1) {
        FATAL(
            "Reference does not look like an object set");
        return -1;
    }

    const char *objset_name =
        crc->elements[0]->value->value.reference->components[0].name;
    if(strcmp(objset_name, opt_ioc->objset->Identifier) != 0) {
        FATAL("Object Set references do not match: %s != %s", objset_name,
              opt_ioc->objset->Identifier);
        return -1;
    }

    if(crc->el_count != 2 || crc->elements[1]->type != ACT_EL_VALUE
       || crc->elements[1]->value->type != ATV_REFERENCED
       || crc->elements[1]->value->value.reference->comp_count != 1) {
        FATAL(
            "Do not know how to handle complex IoS constraints (%d components "
            "of constraint, %d components of reference %s) for %s at line "
            "%d",
            crc->el_count,
            crc->el_count >= 2 && crc->elements[1]->type == ACT_EL_VALUE
                    && crc->elements[1]->value->type == ATV_REFERENCED
                ? (signed)crc->elements[1]->value->value.reference->comp_count
                : -1,
            crc->el_count >= 2 && crc->elements[1]->type == ACT_EL_VALUE
                    && crc->elements[1]->value->type == ATV_REFERENCED
                ? asn1p_ref_string(crc->elements[1]->value->value.reference)
                : "?",
            MKID(parent_expr), parent_expr->_lineno);
        OUT("0");
        return -1;
    }

    const asn1p_ref_t *cref = crc->elements[1]->value->value.reference;
    const char *cname = cref->components[0].name;
    if(cname[0] == '@' && cname[1] != '.') {
        cname += 1;
    } else if(cname[0] == '@' && cname[1] == '.' && cname[2] != '.') {
        cname += 2;
    } else {
        FATAL("Complex IoS reference %s can not be processed",
              asn1p_ref_string(cref));
        OUT("0");
        return -1;
    }

    assert(opt_ioc != NULL);

	asn1p_expr_t *constraining_memb = NULL;
	TQ_FOR(constraining_memb, &(parent_expr->members), next) {
        if(strcmp(constraining_memb->Identifier, cname) == 0)
            break;
    }
    if(!constraining_memb) {
        FATAL("Can not find \"%s\" in %s at line %d", cname, MKID(parent_expr),
              parent_expr->_lineno);
        return -1;
    }

    if(constraining_memb->meta_type != AMT_TYPEREF
       || constraining_memb->expr_type != A1TC_REFERENCE
       || constraining_memb->reference->comp_count != 2
       || constraining_memb->reference->components[1].lex_type
              != RLT_Amplowercase) {
        FATAL(
            "Does not look like %s is a CLASS field reference (%s) on line "
            "%d",
            MKID(constraining_memb),
            constraining_memb->reference
                ? asn1p_ref_string(constraining_memb->reference)
                : "<no reference>",
            constraining_memb->_lineno);
        return -1;
    }
    const char *cfield = constraining_memb->reference->components[1].name;

    ssize_t constraining_column = -1;
    for(size_t cn = 0; cn < opt_ioc->ioct->rows ? opt_ioc->ioct->row[0]->columns : 0;
        cn++) {
        if(strcmp(cfield, opt_ioc->ioct->row[0]->column[cn].field->Identifier)
           == 0) {
            constraining_column = cn;
            break;
        }
    }
    if(constraining_column < 0) {
        FATAL("Can not find referenced object class column %s\n", cfield);
        return -1;
    }

    if(expr->meta_type != AMT_TYPEREF
       || expr->expr_type != A1TC_REFERENCE
       || expr->reference->comp_count != 2
       || expr->reference->components[1].lex_type
              != RLT_AmpUppercase) {
        FATAL(
            "Does not look like %s is a CLASS field reference (%s) denoting a type on line "
            "%d",
            MKID(expr),
            expr->reference
                ? asn1p_ref_string(expr->reference)
                : "<no reference>",
            expr->_lineno);
        return -1;
    }
    const char *for_field = expr->reference->components[1].name;

    ssize_t for_column = -1;
    for(size_t cn = 0; cn < opt_ioc->ioct->rows ? opt_ioc->ioct->row[0]->columns : 0;
        cn++) {
        if(strcmp(for_field,
                  opt_ioc->ioct->row[0]->column[cn].field->Identifier)
           == 0) {
            for_column = cn;
            break;
        }
    }
    if(for_column < 0) {
        FATAL("Can not find referenced object class column %s\n", for_field);
        return -1;
    }


    REDIR(OT_CODE);
    OUT("static asn_TYPE_descriptor_t *\n");
    OUT("select_%s_type(const asn_TYPE_descriptor_t *parent_type, const void *parent_sptr) {\n", MKID_safe(expr));
    INDENT(+1);

    OUT("asn_ioc_set_t *itable = asn_IOS_%s_%d;\n", MKID(opt_ioc->objset),
        opt_ioc->objset->_type_unique_index);
    OUT("size_t constraining_column = %zu; /* %s */\n", constraining_column, cfield);
    OUT("size_t for_column = %zu; /* %s */\n", for_column, for_field);
    OUT("size_t row;\n");

    const char *tname = asn1c_type_name(arg, constraining_memb, TNF_SAFE);
    if(constraining_memb->marker.flags & EM_INDIRECT) {
        OUT("void *memb_ptr = *(const void **)");
        OUT("((const char *)parent_sptr + offsetof(struct ");
            out_name_chain(arg, ONC_avoid_keywords);
        OUT(", %s));", MKID_safe(constraining_memb));
        OUT("if(!memb_ptr) return NULL;\n");
        OUT("\n");
    }

    switch(asn1c_type_fits_long(arg, constraining_memb)) {
    case FL_NOTFIT:
        OUT("const %s_t *constraining_value = (const %s_t *)", tname, tname);
        break;
    case FL_PRESUMED:
    case FL_FITS_SIGNED:
        OUT("const long *constraining_value = (const long *)");
        break;
    case FL_FITS_UNSIGN:
        OUT("const unsigned long *constraining_value = (const unsigned long *)");
        break;
    }
    if(constraining_memb->marker.flags & EM_INDIRECT) {
        OUT("memb_ptr;\n");
    } else {
        OUT("((const char *)parent_sptr + offsetof(struct ");
            out_name_chain(arg, ONC_avoid_keywords);
        OUT(", %s));\n", MKID_safe(constraining_memb));
    }
    OUT("\n");

    OUT("for(row=0; row < itable->rows_count; row++) {\n");
    OUT("    asn_ioc_cell_s *constraining_cell = itable->rows[row * itable->columns_count + constraining_column];\n");
    OUT("    asn_ioc_cell_s *type_cell = itable->rows[row * itable->columns_count + for_column];\n");
    OUT("    if(constraining_cell->type_descriptor->struct_compare(constraining_cell->type_descriptor, constraining_value, constraining_cell->value_sptr) == 0) {\n");
    OUT("        return type_cell->type_descriptor;\n");
    OUT("    }\n");
    OUT("}\n");


    OUT("\n");
    OUT("return NULL;\n");
    INDENT(-1);
    OUT("}\n");
    OUT("\n");

    REDIR(save_target);
    OUT("select_%s_type", MKID_safe(expr));

    return 0;
}

static int
emit_member_table(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *opt_ioc) {
	int save_target;
	arg_t tmp_arg;
	struct asn1p_type_tag_s outmost_tag_s;
	struct asn1p_type_tag_s *outmost_tag;
	int complex_contents;
	char *p;

	if(asn1f_fetch_outmost_tag(arg->asn,
			expr->module, expr, &outmost_tag_s,
			AFT_IMAGINARY_ANY)) {
		outmost_tag = 0;
	} else {
		outmost_tag = &outmost_tag_s;
	}

	OUT("{ ");

	if(outmost_tag && outmost_tag->tag_value == -1)
		OUT("ATF_OPEN_TYPE | ");
	OUT("%s, ",
		(expr->marker.flags & EM_INDIRECT)?"ATF_POINTER":"ATF_NOFLAGS");
	if((expr->marker.flags & EM_OMITABLE) == EM_OMITABLE) {
		asn1p_expr_t *tv;
		int opts = 0;
		for(tv = expr;
			tv && (tv->marker.flags & EM_OMITABLE) == EM_OMITABLE;
			tv = TQ_NEXT(tv, next), opts++) {
			if(tv->expr_type == A1TC_EXTENSIBLE)
				opts--;
		}
		OUT("%d, ", opts);
	} else {
		OUT("0, ");
	}
	if(expr->_anonymous_type) {
		assert(arg->expr->expr_type == ASN_CONSTR_SET_OF
			|| arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF);
		OUT("0,\n");
	} else {
		OUT("offsetof(struct ");
			out_name_chain(arg, ONC_avoid_keywords);
		OUT(", ");
		if(arg->expr->expr_type == ASN_CONSTR_CHOICE
			&& (!UNNAMED_UNIONS)) OUT("choice.");
		OUT("%s),\n", MKID_safe(expr));
	}
	INDENT(+1);
	if(C99_MODE) OUT(".tag = ");
	if(outmost_tag) {
		if(outmost_tag->tag_value == -1)
			OUT("-1 /* Ambiguous tag (ANY?) */");
		else
			_print_tag(arg, outmost_tag);
	} else {
		OUT("-1 /* Ambiguous tag (CHOICE?) */");
	}

	OUT(",\n");
	if(C99_MODE) OUT(".tag_mode = ");
	if((!(expr->expr_type &  ASN_CONSTR_MASK)
	   || expr->expr_type == ASN_CONSTR_CHOICE)
	&& expr->tag.tag_class) {
		if(expr->tag.tag_mode == TM_IMPLICIT)
		OUT("-1,\t/* IMPLICIT tag at current level */\n");
		else
		OUT("+1,\t/* EXPLICIT tag at current level */\n");
	} else {
		OUT("0,\n");
	}

	complex_contents =
		(expr->expr_type & ASN_CONSTR_MASK)
		|| expr->expr_type == ASN_BASIC_ENUMERATED
		|| (0 /* -- prohibited by X.693:8.3.4 */
			&& expr->expr_type == ASN_BASIC_INTEGER
			&& expr_elements_count(arg, expr))
		|| (expr->expr_type == ASN_BASIC_INTEGER
			&& asn1c_type_fits_long(arg, expr) == FL_FITS_UNSIGN);
	if(C99_MODE) OUT(".type = ");
	OUT("&asn_DEF_");
	if(complex_contents) {
		OUT("%s", MKID(expr));
		if(!(arg->flags & A1C_ALL_DEFS_GLOBAL))
			OUT("_%d", expr->_type_unique_index);
	} else {
		OUT("%s", asn1c_type_name(arg, expr, TNF_SAFE));
	}
	OUT(",\n");


    if(C99_MODE) OUT(".type_selector = ");
    if(opt_ioc) {
        emit_member_type_selector(arg, expr, opt_ioc);
    } else {
        OUT("0");
    }
	OUT(",\n");

	if(C99_MODE) OUT(".memb_constraints = ");
	if(expr->constraints) {
		if(arg->flags & A1C_NO_CONSTRAINTS) {
			OUT("0,\t/* No check because of -fno-constraints */\n");
		} else {
			char *id = MKID(expr);
			if(expr->_anonymous_type
					&& !strcmp(expr->Identifier, "Member"))
				id = asn1c_type_name(arg, expr, TNF_SAFE);
			OUT("memb_%s_constraint_%d,\n", id,
				arg->expr->_type_unique_index);
		}
	} else {
		OUT("0,\t/* Defer constraints checking to the member type */\n");
	}
	if(C99_MODE) OUT(".oer_constraints = ");
	if(arg->flags & A1C_GEN_OER) {
		if(expr->constraints) {
			OUT("&asn_OER_memb_%s_constr_%d,\n",
				MKID(expr),
				expr->_type_unique_index);
		} else {
			OUT("0,\t/* No OER visible constraints */\n");
		}
	} else {
		OUT("0,\t/* OER is not compiled, use -gen-OER */\n");
	}
	if(C99_MODE) OUT(".per_constraints = ");
	if(arg->flags & A1C_GEN_PER) {
		if(expr->constraints) {
			OUT("&asn_PER_memb_%s_constr_%d,\n",
				MKID(expr),
				expr->_type_unique_index);
		} else {
			OUT("0,\t/* No PER visible constraints */\n");
		}
	} else {
		OUT("0,\t/* PER is not compiled, use -gen-PER */\n");
	}
	if(C99_MODE) OUT(".default_value = ");
	if(try_inline_default(arg, expr, 0)) {
	} else {
		OUT("0,\n");
	}
	if(C99_MODE) OUT(".name = ");
	if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member")) {
		OUT("\"\"\n");
	} else {
		OUT("\"%s\"\n", expr->Identifier);
	}
	OUT("},\n");
	INDENT(-1);

	if(!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS))
		return 0;

	save_target = arg->target->target;
	REDIR(OT_CODE);

	if(expr->_anonymous_type && !strcmp(expr->Identifier, "Member"))
		p = asn1c_type_name(arg, expr, TNF_SAFE);
	else
		p = MKID(expr);
	OUT("static int\n");
	OUT("memb_%s_constraint_%d(asn_TYPE_descriptor_t *td, const void *sptr,\n", p, arg->expr->_type_unique_index);
	INDENT(+1);
	OUT("\t\tasn_app_constraint_failed_f *ctfailcb, void *app_key) {\n");
	tmp_arg = *arg;
	tmp_arg.expr = expr;
	DEBUG("member constraint checking code for %s", p);
	if(asn1c_emit_constraint_checking_code(&tmp_arg) == 1) {
		OUT("return td->check_constraints"
			"(td, sptr, ctfailcb, app_key);\n");
	}
	INDENT(-1);
	OUT("}\n");
	OUT("\n");

	if(emit_member_OER_constraints(arg, expr, "memb"))
		return -1;

	if(emit_member_PER_constraints(arg, expr, "memb"))
		return -1;

	REDIR(save_target);

	return 0;
}

/*
 * Generate "asn_DEF_XXX" type definition.
 */
static int
emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec spec) {
	asn1p_expr_t *terminal;
	int using_type_name = 0;
	char *p = MKID(expr);
	char *p2 = (char *)0;

	terminal = asn1f_find_terminal_type_ex(arg->asn, expr);

	if(emit_member_OER_constraints(arg, expr, "type"))
		return -1;

	if(emit_member_PER_constraints(arg, expr, "type"))
		return -1;

	if(HIDE_INNER_DEFS)
		OUT("static /* Use -fall-defs-global to expose */\n");
	OUT("asn_TYPE_descriptor_t asn_DEF_%s", p);
	if(HIDE_INNER_DEFS) OUT("_%d", expr->_type_unique_index);
	OUT(" = {\n");
	INDENT(+1);

		if(expr->_anonymous_type) {
			p = ASN_EXPR_TYPE2STR(expr->expr_type);
			OUT("\"%s\",\n", p?p:"");
			OUT("\"%s\",\n",
				p ? asn1c_make_identifier(AMI_CHECK_RESERVED,
					0, p, 0) : "");
		} else {
			OUT("\"%s\",\n", expr->Identifier);
			OUT("\"%s\",\n", expr->Identifier);
		}

		if(expr->expr_type & ASN_CONSTR_MASK) {
			using_type_name = 1;
			p = asn1c_type_name(arg, arg->expr, TNF_SAFE);
		} else {
			if (expr->expr_type == A1TC_REFERENCE) {
				p2 = strdup(asn1c_type_name(arg, terminal, TNF_SAFE));
			} else {
				p2 = strdup(asn1c_type_name(arg, expr, TNF_SAFE));
			}
			p = MKID(expr);
		}
		if (!p2)
			p2 = strdup(p);

#define FUNCREF(foo)	do {				\
	OUT("%s", p);					\
	if(HIDE_INNER_DEFS && !using_type_name)		\
		OUT("_%d", expr->_type_unique_index);	\
	OUT("_" #foo ",\n");				\
} while(0)

#define FUNCREF2(foo)		\
do {				\
	OUT("%s", p2);		\
	OUT("_" #foo ",\n");	\
} while(0)

		FUNCREF2(free);
		FUNCREF2(print);
		FUNCREF2(compare);
		if (arg->flags & A1C_NO_CONSTRAINTS)
			OUT("0,\t/* No check because of -fno-constraints */\n");
		else
		{
			if (!expr->combined_constraints)
				FUNCREF2(constraint);
			else
				FUNCREF(constraint);
		}
		FUNCREF2(decode_ber);
		FUNCREF2(encode_der);
		FUNCREF2(decode_xer);
		FUNCREF2(encode_xer);

		if(arg->flags & A1C_GEN_OER) {
			FUNCREF2(decode_oer);
			FUNCREF2(encode_oer);
		} else {
			OUT("0, 0,\t/* No OER support, "
				"use \"-gen-OER\" to enable */\n");
		}
		if(arg->flags & A1C_GEN_PER) {
			FUNCREF2(decode_uper);
			FUNCREF2(encode_uper);
		} else {
			OUT("0, 0,\t/* No PER support, "
				"use \"-gen-PER\" to enable */\n");
		}
		if (p2) free(p2);

		if(!terminal || terminal->expr_type == ASN_CONSTR_CHOICE) {
		//if(expr->expr_type == ASN_CONSTR_CHOICE) {
			OUT("CHOICE_outmost_tag,\n");
		} else {
			OUT("0,\t/* Use generic outmost tag fetcher */\n");
		}

		p = MKID(expr);
		if(tags_count) {
			OUT("asn_DEF_%s_tags_%d,\n",
				p, expr->_type_unique_index);
			OUT("sizeof(asn_DEF_%s_tags_%d)\n",
				p, expr->_type_unique_index);
			OUT("\t/sizeof(asn_DEF_%s_tags_%d[0])",
				p, expr->_type_unique_index);
			if(tv_mode == _TVM_SUBSET
			&& tags_count != all_tags_count)
				OUT(" - %d", all_tags_count - tags_count);
			OUT(", /* %d */\n", tags_count);
		} else {
			OUT("0,\t/* No effective tags (pointer) */\n");
			OUT("0,\t/* No effective tags (count) */\n");
		}

		if(all_tags_count && tv_mode == _TVM_DIFFERENT) {
			OUT("asn_DEF_%s_all_tags_%d,\n",
				p, expr->_type_unique_index);
			OUT("sizeof(asn_DEF_%s_all_tags_%d)\n",
				p, expr->_type_unique_index);
			OUT("\t/sizeof(asn_DEF_%s_all_tags_%d[0]), /* %d */\n",
				p, expr->_type_unique_index, all_tags_count);
		} else if(all_tags_count) {
			OUT("asn_DEF_%s_tags_%d,\t/* Same as above */\n",
				p, expr->_type_unique_index);
			OUT("sizeof(asn_DEF_%s_tags_%d)\n",
				p, expr->_type_unique_index);
			OUT("\t/sizeof(asn_DEF_%s_tags_%d[0]), /* %d */\n",
				p, expr->_type_unique_index, all_tags_count);
		} else {
			OUT("0,\t/* No tags (pointer) */\n");
			OUT("0,\t/* No tags (count) */\n");
		}

		if(arg->flags & A1C_GEN_OER) {
			if(expr->constraints
			|| expr->expr_type == ASN_BASIC_ENUMERATED
			|| expr->expr_type == ASN_CONSTR_CHOICE) {
				OUT("&asn_OER_type_%s_constr_%d,\n",
					p, expr->_type_unique_index);
			} else {
				OUT("0,\t/* No OER visible constraints */\n");
			}
		} else {
			OUT("0,\t/* No OER visible constraints */\n");
		}

		if(arg->flags & A1C_GEN_PER) {
			if(expr->constraints
			|| expr->expr_type == ASN_BASIC_ENUMERATED
			|| expr->expr_type == ASN_CONSTR_CHOICE) {
				OUT("&asn_PER_type_%s_constr_%d,\n",
					p, expr->_type_unique_index);
			} else {
				OUT("0,\t/* No PER visible constraints */\n");
			}
		} else {
			OUT("0,\t/* No PER visible constraints */\n");
		}

		if(elements_count ||
			((expr->expr_type == A1TC_REFERENCE) &&
				(terminal->expr_type & ASN_CONSTR_MASK) &&
				expr_elements_count(arg, terminal))) {

			if (expr->expr_type == A1TC_REFERENCE) {
				OUT("asn_MBR_%s_%d,\n", MKID(terminal), terminal->_type_unique_index);

				if(terminal->expr_type == ASN_CONSTR_SEQUENCE_OF
				|| terminal->expr_type == ASN_CONSTR_SET_OF) {
					OUT("%d,\t/* Single element */\n",
						expr_elements_count(arg, terminal));
					assert(expr_elements_count(arg, terminal) == 1);
				} else {
					OUT("%d,\t/* Elements count */\n",
						expr_elements_count(arg, terminal));
				}
			} else {
				OUT("asn_MBR_%s_%d,\n", p, expr->_type_unique_index);

				if(expr->expr_type == ASN_CONSTR_SEQUENCE_OF
				|| expr->expr_type == ASN_CONSTR_SET_OF) {
					OUT("%d,\t/* Single element */\n",
						elements_count);
					assert(elements_count == 1);
				} else {
					OUT("%d,\t/* Elements count */\n",
						elements_count);
				}
			}
		} else {
			if(expr_elements_count(arg, expr))
				OUT("0, 0,\t/* Defined elsewhere */\n");
			else
				OUT("0, 0,\t/* No members */\n");
		}

		switch(spec) {
		case ETD_NO_SPECIFICS:
			if ((expr->expr_type == A1TC_REFERENCE) &&
				((terminal->expr_type & ASN_CONSTR_MASK) ||
				(terminal->expr_type == ASN_BASIC_ENUMERATED) ||
				((terminal->expr_type == ASN_BASIC_INTEGER) &&
				(asn1c_type_fits_long(arg, terminal) == FL_FITS_UNSIGN)))) {
				OUT("&asn_SPC_%s_specs_%d\t/* Additional specs */\n", MKID(terminal), terminal->_type_unique_index);
			} else if ((expr->expr_type == ASN_TYPE_ANY) ||
					(expr->expr_type == ASN_BASIC_BIT_STRING) ||
					(expr->expr_type == ASN_STRING_BMPString) ||
					(expr->expr_type == ASN_BASIC_OCTET_STRING) ||
					(expr->expr_type == ASN_STRING_UniversalString)) {
				OUT("&asn_SPC_%s_specs\t/* Additional specs */\n", asn1c_type_name(arg, expr, TNF_SAFE));
			} else if ((expr->expr_type == A1TC_REFERENCE) &&
					((terminal->expr_type == ASN_TYPE_ANY) ||
					(terminal->expr_type == ASN_BASIC_BIT_STRING) ||
					(terminal->expr_type == ASN_STRING_BMPString) ||
					(terminal->expr_type == ASN_BASIC_OCTET_STRING) ||
					(terminal->expr_type == ASN_STRING_UniversalString))) {
				OUT("&asn_SPC_%s_specs\t/* Additional specs */\n", asn1c_type_name(arg, terminal, TNF_SAFE));
			} else {
				OUT("0\t/* No specifics */\n");
			}
			break;
		case ETD_HAS_SPECIFICS:
			OUT("&asn_SPC_%s_specs_%d\t/* Additional specs */\n",
				p, expr->_type_unique_index);
		}
	INDENT(-1);
	OUT("};\n");
	OUT("\n");

	return 0;
}

static int
expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr) {
	/*
	 * X.680, 25.5, Table 5
	 */
	switch(expr_get_type(arg, expr)) {
	case ASN_BASIC_BOOLEAN:
	case ASN_BASIC_ENUMERATED:
	case ASN_BASIC_NULL:
		return 1;
	case ASN_CONSTR_CHOICE:
		return 2;
	default:
		return 0;
	}
}

static int
out_name_chain(arg_t *arg, enum onc_flags onc_flags) {
	asn1p_expr_t *expr = arg->expr;
	char *id;

	if((arg->flags & A1C_COMPOUND_NAMES
	   || onc_flags & ONC_force_compound_name)
	&& ((expr->expr_type & ASN_CONSTR_MASK)
	   || expr->expr_type == ASN_BASIC_ENUMERATED
	   || ((expr->expr_type == ASN_BASIC_INTEGER
	   	|| expr->expr_type == ASN_BASIC_BIT_STRING)
		&& expr_elements_count(arg, expr))
	   )
	&& expr->parent_expr) {

		arg_t tmparg = *arg;

		tmparg.expr = expr->parent_expr;
		if(0) tmparg.flags &= ~A1C_COMPOUND_NAMES;

		out_name_chain(&tmparg, onc_flags);

		if(expr->parent_expr->Identifier) OUT("__");	/* a separator between id components */

		/* Fall through */
	}

	if(onc_flags & ONC_avoid_keywords)
		id = MKID_safe(expr);
	else
		id = MKID(expr);
	OUT("%s", id);

	return 0;
}

static int
emit_include_dependencies(arg_t *arg) {
	asn1p_expr_t *expr = arg->expr;
	asn1p_expr_t *memb;

	/* Avoid recursive definitions. */
	TQ_FOR(memb, &(expr->members), next) {
		expr_break_recursion(arg, memb);
	}

	TQ_FOR(memb, &(expr->members), next) {

		if(memb->marker.flags & (EM_INDIRECT | EM_UNRECURSE)) {
			if(terminal_structable(arg, memb)) {
				int saved_target = arg->target->target;
				if(saved_target != OT_FWD_DECLS) {
					REDIR(OT_FWD_DECLS);
					OUT("%s;\n",
						asn1c_type_name(arg, memb, TNF_RSAFE));
				}
				REDIR(saved_target);
			}
		}

		if((!(memb->expr_type & ASN_CONSTR_MASK)
			&& memb->expr_type > ASN_CONSTR_MASK)
		|| memb->meta_type == AMT_TYPEREF) {
			if(memb->marker.flags & EM_UNRECURSE) {
				GEN_POSTINCLUDE(asn1c_type_name(arg,
					memb, TNF_INCLUDE));
			} else {
				GEN_INCLUDE(asn1c_type_name(arg,
					memb, TNF_INCLUDE));
			}
		}
	}

	return 0;
}

/*
 * Check if it is better to make this type indirectly accessed via
 * a pointer.
 * This may be the case for the following recursive definition:
 * Type ::= CHOICE { member Type };
 */
static int
expr_break_recursion(arg_t *arg, asn1p_expr_t *expr) {
	int ret;

	if(expr->marker.flags & EM_UNRECURSE)
		return 1;	/* Already broken */

	/* -findirect-choice compiles members of CHOICE as indirect pointers */
	if((arg->flags & A1C_INDIRECT_CHOICE)
	 && arg->expr->expr_type == ASN_CONSTR_CHOICE
	 && (expr_get_type(arg, expr) & ASN_CONSTR_MASK)
	) {
		/* Break cross-reference */
		expr->marker.flags |= EM_INDIRECT | EM_UNRECURSE;
		return 1;
	}

	if((expr->marker.flags & EM_INDIRECT)
	|| arg->expr->expr_type == ASN_CONSTR_SET_OF
	|| arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF) {
		if(terminal_structable(arg, expr)) {
			expr->marker.flags |= EM_UNRECURSE;

			if(arg->expr->expr_type == ASN_CONSTR_SET_OF
			|| arg->expr->expr_type == ASN_CONSTR_SEQUENCE_OF) {
				/* Don't put EM_INDIRECT even if recursion */
				return 1;
			}

			/* Fall through */
		}
	}

	/* Look for recursive back-references */
	ret = expr_defined_recursively(arg, expr);
	switch(ret) {
	case 2: /* Explicitly break the recursion */
	case 1: /* Use safer typing */
		expr->marker.flags |= EM_INDIRECT;
		expr->marker.flags |= EM_UNRECURSE;
		break;
	}

	return 0;
}

/*
 * Check if the type can be represented using simple `struct TYPE`.
 */
static asn1p_expr_t *
terminal_structable(arg_t *arg, asn1p_expr_t *expr) {
	asn1p_expr_t *terminal = asn1f_find_terminal_type_ex(arg->asn, expr);
	if(terminal
	&& !terminal->parent_expr
	&& (terminal->expr_type & ASN_CONSTR_MASK)) {
		return terminal;
	}
	return 0;
}

static int
asn1c_recurse(arg_t *arg, asn1p_expr_t *expr, int (*callback)(arg_t *arg, void *key), void *key) {
	arg_t tmp = *arg;
	int maxret = 0;
	int ret;

	if(expr->_mark & TM_RECURSION) return 0;
	expr->_mark |= TM_RECURSION;

	/* Invoke callback for every type going into recursion */
	tmp.expr = expr;
	maxret = callback(&tmp, key);
	if(maxret <= 1) {
		/*
		 * Recursively invoke myself and the callbacks.
		 */
		TQ_FOR(tmp.expr, &(expr->members), next) {
			ret = asn1c_recurse(&tmp, tmp.expr, callback, key);
			if(ret > maxret)
				maxret = ret;
			if(maxret > 1) break;
		}
	}

	expr->_mark &= ~TM_RECURSION;
	return maxret;
}

static int
check_is_refer_to(arg_t *arg, void *key) {
	asn1p_expr_t *terminal = terminal_structable(arg, arg->expr);
	if(terminal == key) {
		if(arg->expr->marker.flags & EM_INDIRECT)
			return 1; /* This is almost safe indirection */
		return 2;
	} else if(terminal) {
		/* This might be N-step circular loop. Dive into it. */
		return asn1c_recurse(arg, terminal, check_is_refer_to, key);
	}
	return 0;
}

/*
 * Check if the possibly inner expression defined recursively.
 */
static int
expr_defined_recursively(arg_t *arg, asn1p_expr_t *expr) {
	asn1p_expr_t *terminal;
	asn1p_expr_t *topmost;

	/* If expression is top-level, there's no way it can be recursive. */
	if(expr->parent_expr == 0) return 0;
	if(expr->expr_type != A1TC_REFERENCE)
		return 0;	/* Basic types are never recursive */

	terminal = terminal_structable(arg, expr);
	if(!terminal) return 0;	/* Terminal cannot be indirected */

	/* Search for the parent container for the given expression */
	topmost = expr;
	while(topmost->parent_expr)
		topmost = topmost->parent_expr;

	/* Look inside the terminal type if it mentions the parent expression */
	return asn1c_recurse(arg, terminal, check_is_refer_to, topmost);
}

struct canonical_map_element {
	int eidx;
	asn1p_expr_t *expr;
};
static int compar_cameo(const void *ap, const void *bp);
static arg_t *cameo_arg;
static int *
compute_canonical_members_order(arg_t *arg, int el_count) {
	struct canonical_map_element *cmap;
	int *rmap;
	asn1p_expr_t *v;
	int eidx = 0;
	int ext_start = -1;
	int nextmax = -1;
	int already_sorted = 1;

	cmap = calloc(el_count, sizeof *cmap);
	assert(cmap);

	TQ_FOR(v, &(arg->expr->members), next) {
		if(v->expr_type != A1TC_EXTENSIBLE) {
			cmap[eidx].eidx = eidx;
			cmap[eidx].expr = v;
			eidx++;
		} else if(ext_start == -1)
			ext_start = eidx;
	}

	cameo_arg = arg;
	if(ext_start == -1) {
		/* Sort the whole thing */
		qsort(cmap, el_count, sizeof(*cmap), compar_cameo);
	} else {
		/* Sort root and extensions independently */
		qsort(cmap, ext_start, sizeof(*cmap), compar_cameo);
		qsort(cmap + ext_start, el_count - ext_start,
			sizeof(*cmap), compar_cameo);
	}

	/* move data back to a simpler map */
	rmap = calloc(el_count, sizeof *rmap);
	assert(rmap);
	for(eidx = 0; eidx < el_count; eidx++) {
		rmap[eidx] = cmap[eidx].eidx;
		if(rmap[eidx] <= nextmax)
			already_sorted = 0;
		else
			nextmax = rmap[eidx];
	}
	free(cmap);

	if(already_sorted) { free(rmap); rmap = 0; }
	return rmap;
}
static int compar_cameo(const void *ap, const void *bp) {
	const struct canonical_map_element *a = (const void *)ap;
	const struct canonical_map_element *b = (const void *)bp;
	struct asn1p_type_tag_s atag, btag;
	arg_t *arg = cameo_arg;

	if(asn1f_fetch_outmost_tag(arg->asn, a->expr->module, a->expr,
			&atag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE))
		return 1;

	if(asn1f_fetch_outmost_tag(arg->asn, b->expr->module, b->expr,
			&btag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE))
		return -1;

	if(atag.tag_class < btag.tag_class)
		return -1;
	if(atag.tag_class > btag.tag_class)
		return 1;
	if(atag.tag_value < btag.tag_value)
		return -1;
	if(atag.tag_value > btag.tag_value)
		return 1;
	return 0;

}
