+static
+struct type_struct *lookup_struct_type_scope(GQuark struct_name,
+ struct type_scope *scope)
+{
+ return g_hash_table_lookup(scope->struct_types,
+ (gconstpointer) (unsigned long) struct_name);
+}
+
+struct type_struct *lookup_struct_type(GQuark struct_name,
+ struct type_scope *scope)
+{
+ struct type_struct *type;
+
+ while (scope) {
+ type = lookup_struct_type_scope(struct_name, scope);
+ if (type)
+ return type;
+ scope = scope->parent_scope;
+ }
+ return NULL;
+}
+
+int register_struct_type(GQuark struct_name, struct type_struct *struct_type,
+ struct type_scope *scope)
+{
+ if (!struct_name)
+ return -EPERM;
+
+ /* Only lookup in local scope */
+ if (lookup_struct_type_scope(struct_name, scope))
+ return -EEXIST;
+
+ g_hash_table_insert(scope->struct_types,
+ (gpointer) (unsigned long) struct_name,
+ struct_type);
+ type_ref(&struct_type->p);
+ return 0;
+}
+
+static
+struct type_variant *lookup_variant_type_scope(GQuark variant_name,
+ struct type_scope *scope)
+{
+ return g_hash_table_lookup(scope->variant_types,
+ (gconstpointer) (unsigned long) variant_name);
+}
+
+struct type_variant *lookup_variant_type(GQuark variant_name,
+ struct type_scope *scope)
+{
+ struct type_variant *type;
+
+ while (scope) {
+ type = lookup_variant_type_scope(variant_name, scope);
+ if (type)
+ return type;
+ scope = scope->parent_scope;
+ }
+ return NULL;
+}
+
+int register_variant_type(GQuark variant_name,
+ struct type_variant *variant_type,
+ struct type_scope *scope)
+{
+ if (!variant_name)
+ return -EPERM;
+
+ /* Only lookup in local scope */
+ if (lookup_variant_type_scope(variant_name, scope))
+ return -EEXIST;
+
+ g_hash_table_insert(scope->variant_types,
+ (gpointer) (unsigned long) variant_name,
+ variant_type);
+ type_ref(&variant_type->p);
+ return 0;
+}
+
+static
+struct type_enum *lookup_enum_type_scope(GQuark enum_name,
+ struct type_scope *scope)
+{
+ return g_hash_table_lookup(scope->enum_types,
+ (gconstpointer) (unsigned long) enum_name);
+}
+
+struct type_enum *lookup_enum_type(GQuark enum_name,
+ struct type_scope *scope)
+{
+ struct type_enum *type;
+
+ while (scope) {
+ type = lookup_enum_type_scope(enum_name, scope);
+ if (type)
+ return type;
+ scope = scope->parent_scope;
+ }
+ return NULL;
+}
+
+int register_enum_type(GQuark enum_name, struct type_enum *enum_type,
+ struct type_scope *scope)
+{
+ if (!enum_name)
+ return -EPERM;
+
+ /* Only lookup in local scope */
+ if (lookup_enum_type_scope(enum_name, scope))
+ return -EEXIST;
+
+ g_hash_table_insert(scope->enum_types,
+ (gpointer) (unsigned long) enum_name,
+ enum_type);
+ type_ref(&enum_type->p);
+ return 0;
+}
+
+struct definition_scope *
+ new_definition_scope(struct definition_scope *parent_scope)