parameterized referencing of information object sets
diff --git a/libasn1compiler/Makefile.am b/libasn1compiler/Makefile.am
index d13a8c0..590ae28 100644
--- a/libasn1compiler/Makefile.am
+++ b/libasn1compiler/Makefile.am
@@ -4,6 +4,7 @@
 AM_CPPFLAGS =                       \
     -I$(top_srcdir)/libasn1common   \
     -I$(top_srcdir)/libasn1parser   \
+    -I$(top_srcdir)/libasn1print    \
     -I$(top_srcdir)/libasn1fix
 
 noinst_LTLIBRARIES = libasn1compiler.la
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index 58d119f..a6066a3 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -8,6 +8,7 @@
 #include "asn1c_out.h"
 #include "asn1c_misc.h"
 #include "asn1c_ioc.h"
+#include <asn1print.h>
 #include <asn1fix_crange.h>	/* constraint groker from libasn1fix */
 #include <asn1fix_export.h>	/* other exportables from libasn1fix */
 #include <asn1parser.h>
@@ -320,6 +321,7 @@
        && expr->reference->comp_count == 2
        && expr->reference->components[1].lex_type
               == RLT_AmpUppercase) {
+        DEBUG("%s is a true open type", MKID(expr));
         return 1;
     }
 
@@ -461,7 +463,8 @@
 			}
 			if(v->marker.flags & EM_OMITABLE)
 			    comp_mode == 1 ? ++aoms_count : ++roms_count;
-			emit_member_table(arg, v, opt_ioc);
+			if(emit_member_table(arg, v, opt_ioc) < 0)
+				return -1;
 			elements++;
 		});
 		OUT("};\n");
@@ -2709,16 +2712,16 @@
         return 0;
     }
 
-    if(crc->el_count <= 1 || crc->elements[0]->type != ACT_EL_VALUE
-       || crc->elements[0]->value->type != ATV_REFERENCED
-       || crc->elements[0]->value->value.reference->comp_count != 1) {
-        FATAL(
-            "Reference does not look like an object set");
+    const asn1p_ref_t *objset_ref =
+        asn1c_get_information_object_set_reference_from_constraint(arg, crc);
+
+    if(!objset_ref || objset_ref->comp_count != 1) {
+        FATAL("Reference %s does not look like an object set type %s",
+              asn1p_constraint_string(crc), asn1p_ref_string(objset_ref));
         return -1;
     }
 
-    const char *objset_name =
-        crc->elements[0]->value->value.reference->components[0].name;
+    const char *objset_name = objset_ref->components[0].name;
     if(strcmp(objset_name, opt_ioc->objset->Identifier) != 0) {
         FATAL("Object Set references do not match: %s != %s", objset_name,
               opt_ioc->objset->Identifier);
@@ -3006,7 +3009,8 @@
 
     if(C99_MODE) OUT(".type_selector = ");
     if(opt_ioc) {
-        emit_member_type_selector(arg, expr, opt_ioc);
+        if(emit_member_type_selector(arg, expr, opt_ioc) < 0)
+            return -1;
     } else {
         OUT("0");
     }
diff --git a/libasn1compiler/asn1c_ioc.c b/libasn1compiler/asn1c_ioc.c
index 7eed3f5..37719d1 100644
--- a/libasn1compiler/asn1c_ioc.c
+++ b/libasn1compiler/asn1c_ioc.c
@@ -3,6 +3,7 @@
 #include "asn1c_out.h"
 #include "asn1c_misc.h"
 #include <asn1fix_export.h>
+#include <asn1print.h>
 
 #define MKID(expr) asn1c_make_identifier(0, (expr), 0)
 
@@ -10,18 +11,26 @@
  * Given the table constraint or component relation constraint
  * ({ObjectSetName}{...}) returns "ObjectSetName" as a reference.
  */
-static const asn1p_ref_t *
-asn1c_get_information_object_set_reference_from_constraint(
+const asn1p_ref_t *
+asn1c_get_information_object_set_reference_from_constraint(arg_t *arg,
     const asn1p_constraint_t *ct) {
 
     if(!ct) return NULL;
     assert(ct->type == ACT_CA_CRC);
     assert(ct->el_count >= 1);
 
+    DEBUG("Component Relation Constraint: %s", asn1p_constraint_string(ct));
+
     assert(ct->elements[0]->type == ACT_EL_VALUE);
 
     asn1p_value_t *val = ct->elements[0]->value;
-    assert(val->type == ATV_REFERENCED);
+    if(val->type == ATV_VALUESET && val->value.constraint->type == ACT_EL_TYPE && val->value.constraint->containedSubtype && val->value.constraint->containedSubtype->type == ATV_REFERENCED) {
+        return val->value.constraint->containedSubtype->value.reference;
+    }
+    if(val->type != ATV_REFERENCED) {
+        FATAL("Set reference: %s", asn1f_printable_value(val));
+        assert(val->type == ATV_REFERENCED);
+    }
 
     return val->value.reference;
 }
@@ -53,17 +62,12 @@
     asn1c_ioc_table_and_objset_t safe_ioc_tao = {0, 0, 0};
     asn1c_ioc_table_and_objset_t failed_ioc_tao = { 0, 0, 1 };
 
-    if(expr->lhs_params) {
-        if(0) WARNING(
-            "Can not process Information Object Set on a parameterized type %s",
-            MKID(expr));
-        return safe_ioc_tao;
-    }
-
     TQ_FOR(memb, &(expr->members), next) {
+        const asn1p_constraint_t *cr_ct =
+            asn1p_get_component_relation_constraint(memb->constraints);
         const asn1p_ref_t *tmpref =
-            asn1c_get_information_object_set_reference_from_constraint(
-                asn1p_get_component_relation_constraint(memb->constraints));
+            asn1c_get_information_object_set_reference_from_constraint(arg,
+                                                                       cr_ct);
         if(tmpref) {
             if(objset_ref && asn1p_ref_compare(objset_ref, tmpref) != 0) {
                 FATAL(
@@ -74,6 +78,7 @@
             }
             objset_ref = tmpref;
         }
+
     }
 
     if(!objset_ref) {
diff --git a/libasn1compiler/asn1c_ioc.h b/libasn1compiler/asn1c_ioc.h
index face3a1..d1a4b4c 100644
--- a/libasn1compiler/asn1c_ioc.h
+++ b/libasn1compiler/asn1c_ioc.h
@@ -15,5 +15,8 @@
 int emit_ioc_table(arg_t *arg, asn1p_expr_t *context,
                     asn1c_ioc_table_and_objset_t);
 
+const asn1p_ref_t *asn1c_get_information_object_set_reference_from_constraint(
+    arg_t *arg, const asn1p_constraint_t *ct);
+
 
 #endif	/* ASN1_IOC_H */