BIT STRING enumerations

diff --git a/ChangeLog b/ChangeLog
index 9110c67..04a332c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,7 @@
 	* The obsolete X.208 syntax is handled gracefully now (compound types'
 	  member names are invented on the fly). (Test case 87).
 	* Generating enumeration tables for INTEGER types (Test case 88).
+	* Generating enumeration tables for BIT STRING types (Test case 89).
 
 0.9.17:	2005-Aug-07
 
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 696ce0a..f91da76 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -214,6 +214,44 @@
 }
 
 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 eidx = 0;
+
+	if(el_count) {
+		REDIR(OT_DEPS);
+		OUT("typedef enum ");
+			out_name_chain(arg, 1);
+		OUT(" {\n");
+		TQ_FOR(v, &(expr->members), next) {
+			switch(v->expr_type) {
+			case A1TC_UNIVERVAL:
+				OUT("\t");
+				out_name_chain(arg, 0);
+				OUT("_%s", MKID(v->Identifier));
+				OUT("\t= %" PRIdASN "%s\n",
+					v->value->value.v_integer,
+					(eidx+1 < el_count) ? "," : "");
+				eidx++;
+				break;
+			default:
+				OUT("/* Unexpected BIT STRING element: %s */\n",
+				v->Identifier);
+				break;
+			}
+		}
+		OUT("} ");
+			out_name_chain(arg, 0);
+		OUT("_e;\n");
+		assert(eidx == el_count);
+	}
+
+	return asn1c_lang_C_type_SIMPLE_TYPE(arg);
+}
+
+int
 asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
 	asn1p_expr_t *expr = arg->expr;
 	asn1p_expr_t *v;
@@ -1914,7 +1952,8 @@
 	if(arg->flags & A1C_COMPOUND_NAMES
 	&& ((expr->expr_type & ASN_CONSTR_MASK)
 	   || expr->expr_type == ASN_BASIC_ENUMERATED
-	   || (expr->expr_type == ASN_BASIC_INTEGER
+	   || ((expr->expr_type == ASN_BASIC_INTEGER
+	   	|| expr->expr_type == ASN_BASIC_BIT_STRING)
 		&& expr_elements_count(arg, expr))
 	   )
 	&& expr->parent_expr
diff --git a/libasn1compiler/asn1c_C.h b/libasn1compiler/asn1c_C.h
index 76fce34..49362f4 100644
--- a/libasn1compiler/asn1c_C.h
+++ b/libasn1compiler/asn1c_C.h
@@ -12,6 +12,7 @@
 int asn1c_lang_C_type_CHOICE(arg_t *);
 
 int asn1c_lang_C_type_common_INTEGER(arg_t *);
+int asn1c_lang_C_type_BIT_STRING(arg_t *);
 int asn1c_lang_C_type_REAL(arg_t *);
 int asn1c_lang_C_type_SIMPLE_TYPE(arg_t *);
 
@@ -41,7 +42,7 @@
 	{ AMT_TYPE, ASN_BASIC_INTEGER,	asn1c_lang_C_type_common_INTEGER },
 	{ AMT_TYPE, ASN_BASIC_REAL,	asn1c_lang_C_type_REAL },
 	{ AMT_TYPE, ASN_BASIC_ENUMERATED,  asn1c_lang_C_type_common_INTEGER },
-	{ AMT_TYPE, ASN_BASIC_BIT_STRING,	asn1c_lang_C_type_SIMPLE_TYPE },
+	{ AMT_TYPE, ASN_BASIC_BIT_STRING,	asn1c_lang_C_type_BIT_STRING },
 	{ AMT_TYPE, ASN_BASIC_OCTET_STRING,	asn1c_lang_C_type_SIMPLE_TYPE },
 	{ AMT_TYPE, ASN_BASIC_OBJECT_IDENTIFIER,asn1c_lang_C_type_SIMPLE_TYPE },
 	{ AMT_TYPE, ASN_BASIC_RELATIVE_OID,	asn1c_lang_C_type_SIMPLE_TYPE },
diff --git a/tests/72-same-names-OK.asn1.-P b/tests/72-same-names-OK.asn1.-P
index 0014fe1..3433fd1 100644
--- a/tests/72-same-names-OK.asn1.-P
+++ b/tests/72-same-names-OK.asn1.-P
@@ -322,6 +322,9 @@
 	Type2_PR_one_name,
 	Type2_PR_two_name,
 } Type2_PR;
+typedef enum a {
+	a_one	= 0
+} a_e;
 
 /*
  * Method of determining the components presence
@@ -329,6 +332,9 @@
 typedef enum two_name_PR {
 	two_name_PR_another_name,	/* Member another_name is present */
 } two_name_PR;
+typedef enum a {
+	a_one	= 0
+} a_e;
 
 /*** <<< TYPE-DECLS [Type2] >>> ***/
 
diff --git a/tests/89-bit-string-enum-OK.asn1 b/tests/89-bit-string-enum-OK.asn1
new file mode 100644
index 0000000..a47a729
--- /dev/null
+++ b/tests/89-bit-string-enum-OK.asn1
@@ -0,0 +1,18 @@
+
+-- OK: Everything is fine
+
+-- iso.org.dod.internet.private.enterprise (1.3.6.1.4.1)
+-- .spelio.software.asn1c.test (9363.1.5.1)
+-- .89
+
+ModuleIntegerEnumeration
+	{ iso org(3) dod(6) internet (1) private(4) enterprise(1)
+		spelio(9363) software(1) asn1c(5) test(1) 89 }
+DEFINITIONS ::=
+BEGIN
+
+	T ::= CHOICE {
+		bs	BIT STRING { a(1), b(2) }
+	}
+
+END
diff --git a/tests/89-bit-string-enum-OK.asn1.-P b/tests/89-bit-string-enum-OK.asn1.-P
new file mode 100644
index 0000000..0ab33be
--- /dev/null
+++ b/tests/89-bit-string-enum-OK.asn1.-P
@@ -0,0 +1,76 @@
+
+/*** <<< INCLUDES [T] >>> ***/
+
+#include <BIT_STRING.h>
+#include <constr_CHOICE.h>
+
+/*** <<< DEPS [T] >>> ***/
+
+typedef enum T_PR {
+	T_PR_NOTHING,	/* No components present */
+	T_PR_bs,
+} T_PR;
+typedef enum bs {
+	bs_a	= 1,
+	bs_b	= 2
+} bs_e;
+
+/*** <<< TYPE-DECLS [T] >>> ***/
+
+typedef struct T {
+	T_PR present;
+	union {
+		BIT_STRING_t	 bs;
+	} choice;
+	
+	/* Context for parsing across buffer boundaries */
+	asn_struct_ctx_t _asn_ctx;
+} T_t;
+
+/*** <<< FUNC-DECLS [T] >>> ***/
+
+extern asn_TYPE_descriptor_t asn_DEF_T;
+
+/*** <<< STAT-DEFS [T] >>> ***/
+
+static asn_TYPE_member_t asn_MBR_T_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct T, choice.bs),
+		.tag = (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)),
+		.tag_mode = 0,
+		.type = (void *)&asn_DEF_BIT_STRING,
+		.memb_constraints = 0,	/* Defer constraints checking to the member type */
+		.name = "bs"
+		},
+};
+static asn_TYPE_tag2member_t asn_MAP_T_1_tag2el[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)), 0, 0, 0 } /* bs at 15 */
+};
+static asn_CHOICE_specifics_t asn_SPC_T_1_specs = {
+	sizeof(struct T),
+	offsetof(struct T, _asn_ctx),
+	offsetof(struct T, present),
+	sizeof(((struct T *)0)->present),
+	asn_MAP_T_1_tag2el,
+	1,	/* Count of tags in the map */
+	0	/* Whether extensible */
+};
+asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
+	"T",
+	CHOICE_free,
+	CHOICE_print,
+	CHOICE_constraint,
+	CHOICE_decode_ber,
+	CHOICE_encode_der,
+	CHOICE_decode_xer,
+	CHOICE_encode_xer,
+	CHOICE_outmost_tag,
+	0,	/* No effective tags (pointer) */
+	0,	/* No effective tags (count) */
+	0,	/* No tags (pointer) */
+	0,	/* No tags (count) */
+	asn_MBR_T_1,
+	1,	/* Elements count */
+	&asn_SPC_T_1_specs	/* Additional specs */
+};
+
diff --git a/tests/89-bit-string-enum-OK.asn1.-Pfcompound-names b/tests/89-bit-string-enum-OK.asn1.-Pfcompound-names
new file mode 100644
index 0000000..1fe136a
--- /dev/null
+++ b/tests/89-bit-string-enum-OK.asn1.-Pfcompound-names
@@ -0,0 +1,76 @@
+
+/*** <<< INCLUDES [T] >>> ***/
+
+#include <BIT_STRING.h>
+#include <constr_CHOICE.h>
+
+/*** <<< DEPS [T] >>> ***/
+
+typedef enum T_PR {
+	T_PR_NOTHING,	/* No components present */
+	T_PR_bs,
+} T_PR;
+typedef enum T__bs {
+	T__bs_a	= 1,
+	T__bs_b	= 2
+} T__bs_e;
+
+/*** <<< TYPE-DECLS [T] >>> ***/
+
+typedef struct T {
+	T_PR present;
+	union {
+		BIT_STRING_t	 bs;
+	} choice;
+	
+	/* Context for parsing across buffer boundaries */
+	asn_struct_ctx_t _asn_ctx;
+} T_t;
+
+/*** <<< FUNC-DECLS [T] >>> ***/
+
+extern asn_TYPE_descriptor_t asn_DEF_T;
+
+/*** <<< STAT-DEFS [T] >>> ***/
+
+static asn_TYPE_member_t asn_MBR_T_1[] = {
+	{ ATF_NOFLAGS, 0, offsetof(struct T, choice.bs),
+		.tag = (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)),
+		.tag_mode = 0,
+		.type = (void *)&asn_DEF_BIT_STRING,
+		.memb_constraints = 0,	/* Defer constraints checking to the member type */
+		.name = "bs"
+		},
+};
+static asn_TYPE_tag2member_t asn_MAP_T_1_tag2el[] = {
+    { (ASN_TAG_CLASS_UNIVERSAL | (3 << 2)), 0, 0, 0 } /* bs at 15 */
+};
+static asn_CHOICE_specifics_t asn_SPC_T_1_specs = {
+	sizeof(struct T),
+	offsetof(struct T, _asn_ctx),
+	offsetof(struct T, present),
+	sizeof(((struct T *)0)->present),
+	asn_MAP_T_1_tag2el,
+	1,	/* Count of tags in the map */
+	0	/* Whether extensible */
+};
+asn_TYPE_descriptor_t asn_DEF_T = {
+	"T",
+	"T",
+	CHOICE_free,
+	CHOICE_print,
+	CHOICE_constraint,
+	CHOICE_decode_ber,
+	CHOICE_encode_der,
+	CHOICE_decode_xer,
+	CHOICE_encode_xer,
+	CHOICE_outmost_tag,
+	0,	/* No effective tags (pointer) */
+	0,	/* No effective tags (count) */
+	0,	/* No tags (pointer) */
+	0,	/* No tags (count) */
+	asn_MBR_T_1,
+	1,	/* Elements count */
+	&asn_SPC_T_1_specs	/* Additional specs */
+};
+