/*
 * 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 "asn1c_naming.h"
#include <asn1print.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 asn1c_lang_C_OpenType(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc, const char *column_name);
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 = calloc(el_count + 1, sizeof(*v2e));
	assert(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 %s {\n", c_name(arg).members_enum);
		TQ_FOR(v, &(expr->members), next) {
			switch(v->expr_type) {
			case A1TC_UNIVERVAL:
				OUT("\t");
				OUT("%s", c_member_name(arg, 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:
				free(v2e);
				return -1;
			}
		}
		OUT("} %s;\n", c_name(arg).members_name);
		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);

	free(v2e);
	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 %s {\n", c_name(arg).members_enum);
		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("%s", c_member_name(arg, v));
			OUT("\t= %s%s\n",
				asn1p_itoa(v->value->value.v_integer),
				(eidx < el_count) ? "," : "");
		}
		OUT("} %s;\n", c_name(arg).members_name);
		assert(eidx == el_count);
	}

	REDIR(saved_target);

	return asn1c_lang_C_type_SIMPLE_TYPE(arg);
}

/*
 * Check if it is a true open type. That is, type is taken from
 * the Information Object Set driven constraints.
 */
static int
is_open_type(arg_t *arg, asn1p_expr_t *expr, asn1c_ioc_table_and_objset_t *opt_ioc) {

    (void)arg;

    if(!opt_ioc) {
        return 0;
    }

    if(expr->meta_type == AMT_TYPEREF
       && expr->expr_type == A1TC_REFERENCE
       && expr->reference->comp_count == 2
       && expr->reference->components[1].lex_type
              == RLT_AmpUppercase) {
        DEBUG("%s is a true open type", MKID(expr));
        return 1;
    }

    return 0;
}

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("%s {\n", c_name(arg).full_name);
	} else {
		REDIR(OT_TYPE_DECLS);
		OUT("typedef %s {\n", c_name(arg).full_name);
	}

	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);
        if(is_open_type(arg, v, ioc_tao.ioct ? &ioc_tao : 0)) {
            arg_t tmp_arg = *arg;
            tmp_arg.embed++;
            INDENT(+1);
            tmp_arg.expr = v;
            const char *column_name = v->reference->components[1].name;
            if(asn1c_lang_C_OpenType(&tmp_arg, &ioc_tao, column_name)) {
                return -1;
            }
            INDENT(-1);
            tmp_arg.embed--;
            if(v->expr_type != A1TC_EXTENSIBLE) OUT(";\n");
        } else {
            EMBED_WITH_IOCT(v, ioc_tao);
        }
	}

	PCTX_DEF;

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

		REDIR(saved_target);

		OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).base_name);
	} else {
		OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).short_name);
	}

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

static void
emit_tag2member_reference(arg_t *arg, asn1p_expr_t *expr,
                          unsigned tag2el_count) {
    if(tag2el_count) {
        if(C99_MODE) OUT(".tag2el = ");
        OUT("asn_MAP_%s_tag2el_%d,\n", MKID(expr), expr->_type_unique_index);
        if(C99_MODE) OUT(".tag2el_count = ");
        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");
    }
}

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",
			c_name(arg).part_name, 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;
			if(emit_member_table(arg, v, opt_ioc) < 0)
				return -1;
			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(%s),\n", c_name(arg).full_name);
	OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
    emit_tag2member_reference(arg, expr, tag2el_count);
	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;
	const 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 %s {\n", c_name(arg).presence_enum);
	TQ_FOR(v, &(expr->members), next) {
		if(v->expr_type == A1TC_EXTENSIBLE) continue;
		INDENTED(
			OUT("%s,", c_presence_name(arg, v));
			OUT("\t/* Member %s is present */\n", MKID(v));
		);
		mcount++;
	}
	OUT("} %s;\n", c_name(arg).presence_name);

	REDIR(saved_target);

	if(arg->embed) {
		if (expr->_anonymous_type) {
			REDIR(OT_FWD_DEFS);
			OUT("typedef ");
		}
		OUT("%s {\n", c_name(arg).full_name);
	} else {
		REDIR(OT_TYPE_DECLS);
		OUT("typedef %s {\n", c_name(arg).full_name);
	}

	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%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).base_name);

		REDIR(saved_target);

		OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).base_name);
	} else {
		OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).short_name);
	}

	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;
	const 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",
			c_name(arg).part_name, 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(%s),\n", c_name(arg).full_name);
		OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
		OUT("offsetof(%s, _presence_map),\n", c_name(arg).full_name);
		emit_tag2member_reference(arg, expr, tag2el_count);
		p = MKID(expr);
		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("%s {\n", c_name(arg).full_name);
	} else {
		OUT("typedef %s {\n", c_name(arg).full_name);
	}

	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 = memb;
		enum asn1p_expr_marker_e flags = memb->marker.flags;
		arg->embed++;
			tmp = *arg;
			tmp.expr = tmp_memb;
			tmp_memb->marker.flags &= ~EM_INDIRECT;
			tmp_memb->_anonymous_type = 1;
			if(tmp_memb->Identifier == 0) {
				tmp_memb->Identifier = strdup("Member");
				if(0)
				tmp_memb->Identifier = strdup(
					asn1c_make_identifier(0,
						expr, "Member", 0));
				assert(tmp_memb->Identifier);
			}
			tmp.default_cb(&tmp, NULL);
			tmp_memb->marker.flags = flags;
		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%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).base_name);

		REDIR(saved_target);

		OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).base_name);
	} else {
		OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).short_name);
	}

	/*
	 * 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",
		c_name(arg).part_name, 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(%s),\n", c_name(arg).full_name);
		OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
		{
		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;
	int saved_target = arg->target->target;

	DEPENDENCIES;

	REDIR(OT_DEPS);

	OUT("typedef %s {\n", c_name(arg).presence_enum);
	INDENTED(
		int skipComma = 1;
        OUT("%s,\t/* No components present */\n", c_presence_name(arg, 0));
		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("%s", c_presence_name(arg, v));
		}
		OUT("\n");
	);
	OUT("} %s;\n", c_name(arg).presence_name);

	REDIR(saved_target);

	if(arg->embed) {
		if (expr->_anonymous_type) {
			REDIR(OT_FWD_DEFS);
			OUT("typedef ");
		}
		OUT("%s {\n", c_name(arg).full_name);
	} else {
		REDIR(OT_TYPE_DECLS);
		OUT("typedef %s {\n", c_name(arg).full_name);
	}

	INDENTED(
		OUT("%s present;\n", c_name(arg).presence_name);
		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%s;\n", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).base_name);

		REDIR(saved_target);

		OUT("%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).base_name);
	} else {
		OUT("} %s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
			c_name(arg).short_name);
	}

	return asn1c_lang_C_type_CHOICE_def(arg);
}

static ssize_t
find_column_index(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc, const char *column_name) {
    (void)arg;

    if(!opt_ioc || !opt_ioc->ioct || !column_name) {
        return -1;
    }

    if(opt_ioc->ioct->rows == 0) {
        return 0;   /* No big deal. Just no data */
    } else {
        for(size_t clmn = 0; clmn < opt_ioc->ioct->row[0]->columns; clmn++) {
            if(strcmp(opt_ioc->ioct->row[0]->column[clmn].field->Identifier,
                      column_name) == 0) {
                return clmn;
            }
        }
        return -1;
    }

}

static int
asn1c_lang_C_OpenType(arg_t *arg, asn1c_ioc_table_and_objset_t *opt_ioc,
                      const char *column_name) {
    arg_t tmp_arg = *arg;

    ssize_t column_index = find_column_index(arg, opt_ioc, column_name);
    if(column_index < 0) {
        FATAL("Open type generation attempted for %s, incomplete", column_name);
        return -1;
    }

    asn1p_expr_t *open_type_choice =
        asn1p_expr_new(arg->expr->_lineno, arg->expr->module);

    open_type_choice->Identifier = strdup(arg->expr->Identifier);
    open_type_choice->meta_type = AMT_TYPE;
    open_type_choice->expr_type = ASN_CONSTR_OPEN_TYPE;
    open_type_choice->_type_unique_index = arg->expr->_type_unique_index;

    for(size_t row = 0; row < opt_ioc->ioct->rows; row++) {
        struct asn1p_ioc_cell_s *cell =
            &opt_ioc->ioct->row[row]->column[column_index];

        asn1p_expr_t *m = asn1p_expr_clone(cell->value, 0);
        asn1p_expr_add(open_type_choice, m);
    }

    tmp_arg.expr = open_type_choice;
    GEN_INCLUDE_STD("OPEN_TYPE");
    asn1c_lang_C_type_CHOICE(&tmp_arg);
    asn1p_expr_free(tmp_arg.expr);
    return 0;
}

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",
			c_name(arg).part_name, 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 unsigned 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(%s),\n", c_name(arg).full_name);
		OUT("offsetof(%s, _asn_ctx),\n", c_name(arg).full_name);
		OUT("offsetof(%s, present),\n", c_name(arg).full_name);
		OUT("sizeof(((%s *)0)->present),\n", c_name(arg).full_name);
		emit_tag2member_reference(arg, expr, 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 = WITH_MODULE_NAMESPACE(
            arg->expr->module, expr_ns,
            asn1f_class_access_ex(arg->asn, arg->expr->module, expr_ns,
                                  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;
	const 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)
	|| asn1c_REAL_fits(arg, expr) == RL_FITS_FLOAT32
	)
		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;
	}

	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("return td->encoding_constraints.general_constraints"
				"(td, sptr, ctfailcb, app_key);\n");
		}
		INDENT(-1);
		OUT("}\n");
		OUT("\n");
	}

	REDIR(OT_STAT_DEFS);

    /*
     * By default, NativeReal is double. We only override this if
     * (OER) constraints suggested that we may use float.
     */
	if(asn1c_REAL_fits(arg, expr) == RL_FITS_FLOAT32) {
		if(!(expr->_type_referenced)) OUT("static ");
		OUT("const asn_NativeReal_specifics_t asn_SPC_%s_specs_%d = {\n",
			MKID(expr), expr->_type_unique_index);
		INDENT(+1);
		OUT("4\t/* Use 'float' type. */\n");
		INDENT(-1);
		OUT("};\n");
	}

	/*
	 * 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", c_name(arg).type.base_name);
	OUT(" * so here we adjust the DEF accordingly.\n");
	OUT(" */\n");

	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 && expr->_type_referenced) {
            if((expr->expr_type == ASN_BASIC_ENUMERATED)
               || (expr->expr_type == ASN_BASIC_INTEGER)) {
                OUT("extern const asn_INTEGER_specifics_t "
                    "asn_SPC_%s_specs_%d;\n",
                    c_name(arg).base_name, expr->_type_unique_index);
            } else {
                asn1p_expr_t *terminal = WITH_MODULE_NAMESPACE(
                    expr->module, expr_ns,
                    asn1f_find_terminal_type_ex(arg->asn, expr_ns, expr));
                OUT("extern const 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 = WITH_MODULE_NAMESPACE(
        arg->expr->module, expr_ns,
        asn1f_fetch_outmost_tag(arg->asn, expr_ns, 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 = WITH_MODULE_NAMESPACE(
            tmp.expr->module, expr_ns,
            asn1f_lookup_symbol_ex(tmp.asn, expr_ns, 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 = WITH_MODULE_NAMESPACE(
        expr->module, expr_ns,
        asn1f_fetch_tags(arg->asn, expr_ns, 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 = WITH_MODULE_NAMESPACE(
        expr->module, expr_ns,
        asn1f_fetch_tags(arg->asn, expr_ns, 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 = WITH_MODULE_NAMESPACE(
        expr->module, expr_ns,
        asn1f_find_terminal_type_ex(arg->asn, expr_ns, 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, arg->ns, 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(expr_get_type(arg, arg->expr) == ASN_BASIC_REAL) {
        if(range->narrowing == NARROW_FLOAT32) {
            OUT("{ sizeof(float), 0 }");
        } else if(range->narrowing == NARROW_DOUBLE64) {
            OUT("{ sizeof(double), 0 }");
        } else {
            OUT("{ 0, 0 }");
        }
    } else if(range->left.type == ARE_VALUE && range->left.value >= 0
              && range->right.type == ARE_MAX) {
        OUT("{ 0, 1 }");
	} 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(expr_get_type(arg, arg->expr) == ASN_BASIC_REAL) {
        /* Unsupported */
        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->combined_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 CC_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->combined_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 CC_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, arg->ns, 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 &&
		    expr->marker.default_value->type != ATV_TRUE &&
		    expr->marker.default_value->type != ATV_FALSE))
			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;
    }

    const asn1p_ref_t *objset_ref =
        asn1c_get_information_object_set_reference_from_constraint(arg, crc);

    if(!objset_ref) {
        FATAL("Constraint %s does not look like it referst to a set type %s",
              asn1p_constraint_string(crc),
              opt_ioc->objset->Identifier);
        return -1;
    }

    const char *objset_name;
    if(objset_ref->comp_count == 1) {
        objset_name = objset_ref->components[0].name;
    } else if(objset_ref->comp_count == 2) {
        if(strcmp(objset_ref->components[0].name,
                  opt_ioc->objset->module->ModuleName)
           != 0) {
            FATAL(
                "Composite reference %s (from %s) does not look like it refers "
                "to the same module as %s from an object set type %s",
                asn1p_ref_string(objset_ref), asn1p_constraint_string(crc),
                opt_ioc->objset->module->ModuleName,
                opt_ioc->objset->Identifier);
            return -1;
        }
        objset_name = objset_ref->components[1].name;
    } else {
        FATAL("Reference %s (from %s) does not look like an object set type %s",
              asn1p_ref_string(objset_ref), asn1p_constraint_string(crc),
              opt_ioc->objset->Identifier);
        return -1;
    }
    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) {
        if(opt_ioc->ioct->rows == 0) {
            OUT("0");
            return 0;
        } else {
            FATAL("Can not find referenced object class %s column %s\n",
                  asn1p_ref_string(objset_ref), 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_selector_result_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_type_selector_result_t result = {0, 0};\n");
    OUT("const 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("const void *memb_ptr = *(const void **)");
        OUT("((const char *)parent_sptr + offsetof(%s", c_name(arg).full_name);
        OUT(", %s));", MKID_safe(constraining_memb));
        OUT("if(!memb_ptr) return result;\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(%s", c_name(arg).full_name);
        OUT(", %s));\n", MKID_safe(constraining_memb));
    }
    OUT("\n");

    OUT("for(row=0; row < itable->rows_count; row++) {\n");
    OUT("    const asn_ioc_cell_t *constraining_cell = &itable->rows[row * itable->columns_count + constraining_column];\n");
    OUT("    const asn_ioc_cell_t *type_cell = &itable->rows[row * itable->columns_count + for_column];\n");
    OUT("\n");
    OUT("    if(constraining_cell->type_descriptor->op->compare_struct(constraining_cell->type_descriptor, constraining_value, constraining_cell->value_sptr) == 0) {\n");
    OUT("        result.type_descriptor = type_cell->type_descriptor;\n");
    OUT("        result.presence_index = row + 1;\n");
    OUT("        break;\n");
    OUT("    }\n");
    OUT("}\n");


    OUT("\n");
    OUT("return result;\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;
	const char *p;

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

	OUT("{ ");

    if(is_open_type(arg, expr, opt_ioc)) {
        OUT("ATF_OPEN_TYPE | ");
    } else if(outmost_tag && outmost_tag->tag_value == -1) {
        OUT("ATF_ANY_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(%s, ", c_name(arg).full_name);
        if((arg->expr->expr_type == ASN_CONSTR_CHOICE
            || arg->expr->expr_type == ASN_CONSTR_OPEN_TYPE)
           && (!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 =
		is_open_type(arg, expr, opt_ioc)
		|| (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) {
        if(emit_member_type_selector(arg, expr, opt_ioc) < 0)
            return -1;
    } else {
        OUT("0");
    }
	OUT(",\n");

    OUT("{ ");
	if(C99_MODE) OUT(".oer_constraints = ");
	if(arg->flags & A1C_GEN_OER) {
		if(expr->constraints) {
			OUT("&asn_OER_memb_%s_constr_%d",
				MKID(expr),
				expr->_type_unique_index);
		} else {
			OUT("0");
		}
	} else {
        OUT("0");
	}
    OUT(", ");
	if(C99_MODE) OUT(".per_constraints = ");
	if(arg->flags & A1C_GEN_PER) {
		if(expr->constraints) {
			OUT("&asn_PER_memb_%s_constr_%d",
				MKID(expr),
				expr->_type_unique_index);
		} else {
			OUT("0");
		}
	} else {
		OUT("0");
	}
    OUT(", ");
	if(C99_MODE) OUT(".general_constraints = ");
	if(expr->constraints) {
		if(arg->flags & A1C_NO_CONSTRAINTS) {
			OUT("0");
		} else {
			const 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", id,
				arg->expr->_type_unique_index);
		}
	} else {
		OUT("0");
	}
    OUT(" },\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->encoding_constraints.general_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 *expr_id = strdup(MKID(expr));
	char *p = expr_id;
	char *p2 = (char *)0;

	terminal = asn1f_find_terminal_type_ex(arg->asn, arg->ns, 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 || (arg->flags & A1C_ALL_DEFS_GLOBAL))
        OUT("_%d", expr->_type_unique_index);
    OUT(" = {\n");
	INDENT(+1);

		if(expr->_anonymous_type) {
			p = strdup(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 = strdup(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 = strdup(expr_id);
		}
		if (!p2)
			p2 = strdup(p);

        OUT("&asn_OP_%s,\n", p2);

		if(tags_count) {
			OUT("asn_DEF_%s_tags_%d,\n",
				expr_id, expr->_type_unique_index);
			OUT("sizeof(asn_DEF_%s_tags_%d)\n",
				expr_id, expr->_type_unique_index);
			OUT("\t/sizeof(asn_DEF_%s_tags_%d[0])",
				expr_id, 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",
				expr_id, expr->_type_unique_index);
			OUT("sizeof(asn_DEF_%s_all_tags_%d)\n",
				expr_id, expr->_type_unique_index);
			OUT("\t/sizeof(asn_DEF_%s_all_tags_%d[0]), /* %d */\n",
				expr_id, expr->_type_unique_index, all_tags_count);
		} else if(all_tags_count) {
			OUT("asn_DEF_%s_tags_%d,\t/* Same as above */\n",
				expr_id, expr->_type_unique_index);
			OUT("sizeof(asn_DEF_%s_tags_%d)\n",
				expr_id, expr->_type_unique_index);
			OUT("\t/sizeof(asn_DEF_%s_tags_%d[0]), /* %d */\n",
				expr_id, expr->_type_unique_index, all_tags_count);
		} else {
			OUT("0,\t/* No tags (pointer) */\n");
			OUT("0,\t/* No tags (count) */\n");
		}

		OUT("{ ");
		if(arg->flags & A1C_GEN_OER) {
			if(expr->combined_constraints
			|| expr->expr_type == ASN_BASIC_ENUMERATED
			|| expr->expr_type == ASN_CONSTR_CHOICE) {
				OUT("&asn_OER_type_%s_constr_%d",
					expr_id, expr->_type_unique_index);
			} else {
				OUT("0");
			}
		} else {
			OUT("0");
		}
        OUT(", ");

		if(arg->flags & A1C_GEN_PER) {
			if(expr->combined_constraints
			|| expr->expr_type == ASN_BASIC_ENUMERATED
			|| expr->expr_type == ASN_CONSTR_CHOICE) {
				OUT("&asn_PER_type_%s_constr_%d",
					expr_id, expr->_type_unique_index);
			} else {
				OUT("0");
			}
		} else {
			OUT("0");
		}
		OUT(", ");
#define FUNCREF(foo)                              \
    do {                                          \
        OUT("%s", p);                             \
        if(HIDE_INNER_DEFS && !using_type_name)   \
            OUT("_%d", expr->_type_unique_index); \
        OUT("_" #foo "");                         \
    } while(0)

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

        if (arg->flags & A1C_NO_CONSTRAINTS) {
			OUT("0");
		} else {
			if (!expr->combined_constraints)
				FUNCREF2(constraint);
			else
				FUNCREF(constraint);
		}
        OUT(" },\n");

        free(p);
        p = NULL;
        free(p2);
        p2 = NULL;
        free(expr_id);
        expr_id = NULL;

		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", c_name(arg).part_name,
                    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",
                    c_expr_name(arg, terminal).part_name,
                    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",
                    c_name(arg).type.part_name);
            } 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",
                    c_expr_name(arg, terminal).type.part_name);
            } else {
				OUT("0\t/* No specifics */\n");
			}
			break;
		case ETD_HAS_SPECIFICS:
			OUT("&asn_SPC_%s_specs_%d\t/* Additional specs */\n",
				c_name(arg).part_name, 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;
	const char *id;

	if((arg->flags & A1C_COMPOUND_NAMES
	   || onc_flags & ONC_force_compound_name
	   || (0 && arg->embed /* Not yet */))
	&& ((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, arg->ns, 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(WITH_MODULE_NAMESPACE(a->expr->module, expr_ns,
                             asn1f_fetch_outmost_tag(
                                 arg->asn, expr_ns, a->expr->module, a->expr,
                                 &atag, AFT_IMAGINARY_ANY | AFT_CANON_CHOICE)))
        return 1;

    if(WITH_MODULE_NAMESPACE(b->expr->module, expr_ns,
                             asn1f_fetch_outmost_tag(
                                 arg->asn, expr_ns, 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;

}
