unions are not anonymous

diff --git a/ChangeLog b/ChangeLog
index 35c09af..417a4f8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@
 	* Generating enumeration tables for BIT STRING types (Test case 89).
 	* Conditional INTEGER/ENUMERATED representation: long vs. INTEGER_t
 	  type is chosen based on PER visible constraints (Test cases 90, 91).
+	* Union structures for CHOICE type are not anonymous anymore.
 
 0.9.17:	2005-Aug-07
 
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index d39018e..6725f67 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -24,6 +24,12 @@
 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);
 static int asn1c_lang_C_type_SET_def(arg_t *arg);
 static int asn1c_lang_C_type_CHOICE_def(arg_t *arg);
@@ -36,7 +42,6 @@
 static int emit_member_table(arg_t *arg, asn1p_expr_t *expr);
 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 int out_name_chain(arg_t *arg, int check_reserved_keywords);
 
 enum tvm_compat {
 	_TVM_SAME	= 0,	/* tags and all_tags are same */
@@ -117,13 +122,13 @@
 		eidx = 0;
 		REDIR(OT_DEPS);
 		OUT("typedef enum ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(" {\n");
 		TQ_FOR(v, &(expr->members), next) {
 			switch(v->expr_type) {
 			case A1TC_UNIVERVAL:
 				OUT("\t");
-				out_name_chain(arg, 0);
+				out_name_chain(arg, ONC_noflags);
 				OUT("_%s", MKID(v->Identifier));
 				OUT("\t= %" PRIdASN "%s\n",
 					v->value->value.v_integer,
@@ -143,7 +148,7 @@
 			}
 		}
 		OUT("} ");
-			out_name_chain(arg, 0);
+			out_name_chain(arg, ONC_noflags);
 		OUT("_e;\n");
 		assert(eidx == el_count);
 	}
@@ -223,7 +228,7 @@
 		int eidx = 0;
 		REDIR(OT_DEPS);
 		OUT("typedef enum ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(" {\n");
 		TQ_FOR(v, &(expr->members), next) {
 			eidx++;
@@ -233,14 +238,14 @@
 				continue;
 			}
 			OUT("\t");
-			out_name_chain(arg, 0);
+			out_name_chain(arg, ONC_noflags);
 			OUT("_%s", MKID(v->Identifier));
 			OUT("\t= %" PRIdASN "%s\n",
 				v->value->value.v_integer,
 				(eidx < el_count) ? "," : "");
 		}
 		OUT("} ");
-			out_name_chain(arg, 0);
+			out_name_chain(arg, ONC_noflags);
 		OUT("_e;\n");
 		assert(eidx == el_count);
 	}
@@ -258,7 +263,7 @@
 
 	if(arg->embed) {
 		OUT("struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(" {\n");
 	} else {
 		OUT("typedef struct %s {\n",
@@ -352,8 +357,8 @@
 	OUT("static asn_SEQUENCE_specifics_t asn_SPC_%s_%d_specs = {\n",
 		MKID(expr->Identifier), expr->_type_unique_index);
 	INDENTED(
-		OUT("sizeof(struct "); out_name_chain(arg, 1); OUT("),\n");
-		OUT("offsetof(struct "); out_name_chain(arg, 1); OUT(", _asn_ctx),\n");
+		OUT("sizeof(struct "); out_name_chain(arg, ONC_avoid_keywords); OUT("),\n");
+		OUT("offsetof(struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(", _asn_ctx),\n");
 
 		if(tag2el_count) {
 			OUT("asn_MAP_%s_%d_tag2el,\n",
@@ -400,12 +405,12 @@
 	OUT(" */\n");
 	mcount = 0;
 	OUT("typedef enum ");
-		out_name_chain(arg, 0);
+		out_name_chain(arg, ONC_noflags);
 	OUT("_PR {\n");
 	TQ_FOR(v, &(expr->members), next) {
 		if(v->expr_type == A1TC_EXTENSIBLE) continue;
 		INDENTED(
-			out_name_chain(arg, 0);
+			out_name_chain(arg, ONC_noflags);
 			OUT("_PR_");
 			id = MKID(v->Identifier);
 			OUT("%s,\t/* Member %s is present */\n",
@@ -413,13 +418,13 @@
 		);
 		mcount++;
 	}
-	OUT("} "); out_name_chain(arg, 0); OUT("_PR;\n");
+	OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");
 
 	REDIR(OT_TYPE_DECLS);
 
 	if(arg->embed) {
 		OUT("struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(" {\n");
 	} else {
 		OUT("typedef struct %s {\n", MKID_safe(expr->Identifier));
@@ -566,13 +571,13 @@
 		MKID(expr->Identifier), expr->_type_unique_index);
 	INDENTED(
 		OUT("sizeof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT("),\n");
 		OUT("offsetof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(", _asn_ctx),\n");
 		OUT("offsetof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(", _presence_map),\n");
 		p = MKID(expr->Identifier);
 		OUT("asn_MAP_%s_%d_tag2el,\n", p, expr->_type_unique_index);
@@ -612,7 +617,7 @@
 
 	if(arg->embed) {
 		OUT("struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(" {\n");
 	} else {
 		OUT("typedef struct %s {\n", MKID_safe(expr->Identifier));
@@ -715,10 +720,10 @@
 		MKID(expr->Identifier), expr->_type_unique_index);
 	INDENTED(
 		OUT("sizeof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT("),\n");
 		OUT("offsetof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(", _asn_ctx),\n");
 
 		if(expr_as_xmlvaluelist(arg, v))
@@ -750,36 +755,41 @@
 	REDIR(OT_DEPS);
 
 	OUT("typedef enum ");
-		out_name_chain(arg, 0);
+		out_name_chain(arg, ONC_noflags);
 	OUT("_PR {\n");
 	INDENTED(
-		out_name_chain(arg, 0);
+		out_name_chain(arg, ONC_noflags);
 		OUT("_PR_NOTHING,\t/* No components present */\n");
 		TQ_FOR(v, &(expr->members), next) {
 			if(v->expr_type == A1TC_EXTENSIBLE) {
 				OUT("/* Extensions may appear below */\n");
 				continue;
 			}
-			out_name_chain(arg, 0);
+			out_name_chain(arg, ONC_noflags);
 			OUT("_PR_");
 			id = MKID(v->Identifier);
 			OUT("%s,\n", id, id);
 		}
 	);
-	OUT("} "); out_name_chain(arg, 0); OUT("_PR;\n");
+	OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");
 
 	REDIR(OT_TYPE_DECLS);
 
 	if(arg->embed) {
-		OUT("struct "); out_name_chain(arg, 1); OUT(" {\n");
+		OUT("struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(" {\n");
 	} else {
 		OUT("typedef struct %s {\n", MKID_safe(expr->Identifier));
 	}
 
 	INDENTED(
-		out_name_chain(arg, 0);
+		out_name_chain(arg, ONC_noflags);
 		OUT("_PR present;\n");
-		OUT("union {\n");
+		OUT("union ");
+		if(UNNAMED_UNIONS == 0) {
+			out_name_chain(arg, ONC_force_compound_name);
+			OUT("_u ");
+		}
+		OUT("{\n");
 		TQ_FOR(v, &(expr->members), next) {
 			if(expr_better_indirect(arg, v))
 				v->marker.flags |= EM_INDIRECT;
@@ -868,16 +878,16 @@
 		MKID(expr->Identifier), expr->_type_unique_index);
 	INDENTED(
 		OUT("sizeof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT("),\n");
 		OUT("offsetof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(", _asn_ctx),\n");
 		OUT("offsetof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(", present),\n");
 		OUT("sizeof(((struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(" *)0)->present),\n");
 		OUT("asn_MAP_%s_%d_tag2el,\n",
 			MKID(expr->Identifier), expr->_type_unique_index);
@@ -1678,7 +1688,7 @@
 		OUT("0,\n");
 	} else {
 		OUT("offsetof(struct ");
-			out_name_chain(arg, 1);
+			out_name_chain(arg, ONC_avoid_keywords);
 		OUT(", ");
 		if(arg->expr->expr_type == ASN_CONSTR_CHOICE
 			&& (!UNNAMED_UNIONS)) OUT("choice.");
@@ -1940,13 +1950,14 @@
 }
 
 static int
-out_name_chain(arg_t *arg, int check_reserved_keywords) {
+out_name_chain(arg_t *arg, enum onc_flags onc_flags) {
 	asn1p_expr_t *expr = arg->expr;
 	char *id;
 
 	assert(expr->Identifier);
 
-	if(arg->flags & A1C_COMPOUND_NAMES
+	if((arg->flags & A1C_COMPOUND_NAMES
+	   || onc_flags & ONC_force_compound_name)
 	&& ((expr->expr_type & ASN_CONSTR_MASK)
 	   || expr->expr_type == ASN_BASIC_ENUMERATED
 	   || ((expr->expr_type == ASN_BASIC_INTEGER
@@ -1960,14 +1971,14 @@
 		tmparg.expr = expr->parent_expr;
 		if(0) tmparg.flags &= ~A1C_COMPOUND_NAMES;
 
-		out_name_chain(&tmparg, 0);
+		out_name_chain(&tmparg, onc_flags);
 
 		OUT("__");	/* a separator between id components */
 
 		/* Fall through */
 	}
 
-	if(check_reserved_keywords)
+	if(onc_flags & ONC_avoid_keywords)
 		id = MKID_safe(expr->Identifier);
 	else
 		id = MKID(expr->Identifier);
diff --git a/tests/31-set-of-OK.asn1.-P b/tests/31-set-of-OK.asn1.-P
index c7d8f0b..03cd72d 100644
--- a/tests/31-set-of-OK.asn1.-P
+++ b/tests/31-set-of-OK.asn1.-P
@@ -203,7 +203,7 @@
 	 */
 	struct other {
 		other_PR present;
-		union {
+		union Stuff__other_u {
 			INTEGER_t	 a;
 			INTEGER_t	 b;
 		} choice;
diff --git a/tests/42-real-life-OK.asn1.-PR b/tests/42-real-life-OK.asn1.-PR
index 09aed56..f0aef03 100644
--- a/tests/42-real-life-OK.asn1.-PR
+++ b/tests/42-real-life-OK.asn1.-PR
@@ -339,7 +339,7 @@
 
 typedef struct VariablePart {
 	VariablePart_PR present;
-	union {
+	union VariablePart_u {
 		struct vset {
 			A_SET_OF(VisibleString_t) list;
 			
diff --git a/tests/43-recursion-OK.asn1.-P b/tests/43-recursion-OK.asn1.-P
index 02135e7..6d83f61 100644
--- a/tests/43-recursion-OK.asn1.-P
+++ b/tests/43-recursion-OK.asn1.-P
@@ -220,7 +220,7 @@
 
 typedef struct Choice_1 {
 	Choice_1_PR present;
-	union {
+	union Choice_1_u {
 		struct Choice_1	*and;
 		struct or {
 			A_SET_OF(struct Choice_1) list;
diff --git a/tests/44-choice-in-sequence-OK.asn1.-P b/tests/44-choice-in-sequence-OK.asn1.-P
index 936fbe8..bd9dd8d 100644
--- a/tests/44-choice-in-sequence-OK.asn1.-P
+++ b/tests/44-choice-in-sequence-OK.asn1.-P
@@ -31,12 +31,12 @@
 	NULL_t	 a;
 	struct b {
 		b_PR present;
-		union {
+		union T__b_u {
 			NULL_t	 c;
 			NULL_t	 d;
 			struct e {
 				e_PR present;
-				union {
+				union T__b__e_u {
 					NULL_t	 f;
 					NULL_t	 g;
 				} choice;
@@ -46,7 +46,7 @@
 			} e;
 			struct h {
 				h_PR present;
-				union {
+				union T__b__h_u {
 					NULL_t	 i;
 					NULL_t	 j;
 				} choice;
diff --git a/tests/47-set-ext-OK.asn1.-P b/tests/47-set-ext-OK.asn1.-P
index 660048b..72d605b 100644
--- a/tests/47-set-ext-OK.asn1.-P
+++ b/tests/47-set-ext-OK.asn1.-P
@@ -196,7 +196,7 @@
 
 typedef struct T3 {
 	T3_PR present;
-	union {
+	union T3_u {
 		INTEGER_t	 i;
 		/*
 		 * This type is extensible,
@@ -273,7 +273,7 @@
 
 typedef struct T4 {
 	T4_PR present;
-	union {
+	union T4_u {
 		INTEGER_t	 i;
 		/*
 		 * This type is extensible,
diff --git a/tests/59-choice-extended-OK.asn1.-P b/tests/59-choice-extended-OK.asn1.-P
index 391cbca..f7f8a2c 100644
--- a/tests/59-choice-extended-OK.asn1.-P
+++ b/tests/59-choice-extended-OK.asn1.-P
@@ -23,7 +23,7 @@
 
 typedef struct Choice {
 	Choice_PR present;
-	union {
+	union Choice_u {
 		INTEGER_t	 a;
 		/*
 		 * This type is extensible,
diff --git a/tests/70-xer-test-OK.asn1.-P b/tests/70-xer-test-OK.asn1.-P
index 26c651a..74c0b1d 100644
--- a/tests/70-xer-test-OK.asn1.-P
+++ b/tests/70-xer-test-OK.asn1.-P
@@ -34,7 +34,7 @@
 
 typedef struct PDU {
 	PDU_PR present;
-	union {
+	union PDU_u {
 		Sequence_t	 sequence;
 		Set_t	 set;
 		SetOf_t	 setOf;
diff --git a/tests/72-same-names-OK.asn1.-P b/tests/72-same-names-OK.asn1.-P
index 3433fd1..1e8b3e3 100644
--- a/tests/72-same-names-OK.asn1.-P
+++ b/tests/72-same-names-OK.asn1.-P
@@ -141,7 +141,7 @@
 typedef struct Type1 {
 	struct one_name {
 		one_name_PR present;
-		union {
+		union Type1__one_name_u {
 			struct another_name {
 				INTEGER_t	 a;
 				INTEGER_t	 b;
@@ -340,7 +340,7 @@
 
 typedef struct Type2 {
 	Type2_PR present;
-	union {
+	union Type2_u {
 		struct one_name {
 			struct another_name {
 				BIT_STRING_t	 a;
diff --git a/tests/84-param-tags-OK.asn1.-P b/tests/84-param-tags-OK.asn1.-P
index 282dfe4..b45977b 100644
--- a/tests/84-param-tags-OK.asn1.-P
+++ b/tests/84-param-tags-OK.asn1.-P
@@ -18,7 +18,7 @@
 
 typedef struct TestChoice {
 	TestChoice_PR present;
-	union {
+	union TestChoice_u {
 		struct type1 {
 			long	*common	/* DEFAULT 0 */;
 			
@@ -233,7 +233,7 @@
 
 typedef struct AutoChoice {
 	AutoChoice_PR present;
-	union {
+	union AutoChoice_u {
 		struct type1 {
 			long	 common;
 			
diff --git a/tests/89-bit-string-enum-OK.asn1.-P b/tests/89-bit-string-enum-OK.asn1.-P
index 0ab33be..3cd1f35 100644
--- a/tests/89-bit-string-enum-OK.asn1.-P
+++ b/tests/89-bit-string-enum-OK.asn1.-P
@@ -19,7 +19,7 @@
 
 typedef struct T {
 	T_PR present;
-	union {
+	union T_u {
 		BIT_STRING_t	 bs;
 	} choice;
 	
diff --git a/tests/89-bit-string-enum-OK.asn1.-Pfcompound-names b/tests/89-bit-string-enum-OK.asn1.-Pfcompound-names
index 1fe136a..9ac69a2 100644
--- a/tests/89-bit-string-enum-OK.asn1.-Pfcompound-names
+++ b/tests/89-bit-string-enum-OK.asn1.-Pfcompound-names
@@ -19,7 +19,7 @@
 
 typedef struct T {
 	T_PR present;
-	union {
+	union T_u {
 		BIT_STRING_t	 bs;
 	} choice;