[g-ir-compiler] Slightly less lame error messages
[gnome.gobject-introspection] / girepository / girnode.c
index 7734bf9..2523ee1 100644 (file)
@@ -1,6 +1,7 @@
 /* GObject introspection: Typelib creation
  *
  * Copyright (C) 2005 Matthias Clasen
+ * Copyright (C) 2008,2009 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -34,7 +35,7 @@ static gulong types_count = 0;
 static gulong unique_types_count = 0;
 
 void
-init_stats (void)
+_g_irnode_init_stats (void)
 {
   string_count = 0;
   unique_string_count = 0;
@@ -45,7 +46,7 @@ init_stats (void)
 }
 
 void
-dump_stats (void)
+_g_irnode_dump_stats (void)
 {
   g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
             unique_string_count, string_count, unique_string_size, string_size);
@@ -56,7 +57,7 @@ dump_stats (void)
   (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
 
 
-static const gchar *
+const gchar *
 g_ir_node_type_to_string (GIrNodeTypeId type)
 {
   switch (type)
@@ -104,68 +105,6 @@ g_ir_node_type_to_string (GIrNodeTypeId type)
     }
 }
 
-static const gchar*
-gi_type_tag_to_string (GITypeTag type)
-{
-  switch (type)
-    {
-    case GI_TYPE_TAG_VOID:
-      return "void";
-    case GI_TYPE_TAG_BOOLEAN:
-      return "boolean";
-    case GI_TYPE_TAG_INT8:
-      return "int8";
-    case GI_TYPE_TAG_UINT8:
-      return "uint8";
-    case GI_TYPE_TAG_INT16:
-      return "int16";
-    case GI_TYPE_TAG_UINT16:
-      return "uint16";
-    case GI_TYPE_TAG_INT32:
-      return "int32";
-    case GI_TYPE_TAG_UINT32:
-      return "uint32";
-    case GI_TYPE_TAG_INT64:
-      return "int64";
-    case GI_TYPE_TAG_UINT64:
-      return "uint64";
-    case GI_TYPE_TAG_INT:
-      return "int";
-    case GI_TYPE_TAG_UINT:
-      return "uint";
-    case GI_TYPE_TAG_LONG:
-      return "long";
-    case GI_TYPE_TAG_ULONG:
-      return "ulong";
-    case GI_TYPE_TAG_SSIZE:
-      return "ssize";
-    case GI_TYPE_TAG_SIZE:
-      return "size";
-    case GI_TYPE_TAG_FLOAT:
-      return "float";
-    case GI_TYPE_TAG_DOUBLE:
-      return "double";
-    case GI_TYPE_TAG_UTF8:
-      return "utf8";
-    case GI_TYPE_TAG_FILENAME:
-      return "filename";
-    case GI_TYPE_TAG_ARRAY:
-      return "array";
-    case GI_TYPE_TAG_INTERFACE:
-      return "interface";
-    case GI_TYPE_TAG_GLIST:
-      return "glist";
-    case GI_TYPE_TAG_GSLIST:
-      return "gslist";
-    case GI_TYPE_TAG_GHASH:
-      return "ghash";
-    case GI_TYPE_TAG_ERROR:
-      return "error";
-    default:
-      return "unknown";
-    }
-}
-
 GIrNode *
 g_ir_node_new (GIrNodeTypeId type)
 {
@@ -246,6 +185,9 @@ g_ir_node_new (GIrNodeTypeId type)
     }
 
   node->type = type;
+  node->offset = 0;
+  node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                            g_free, g_free);
 
   return node;
 }
@@ -323,6 +265,7 @@ g_ir_node_free (GIrNode *node)
        GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
        
        g_free (node->name);
+       g_free (vfunc->invoker);
        for (l = vfunc->parameters; l; l = l->next)
          g_ir_node_free ((GIrNode *)l->data);
        g_list_free (vfunc->parameters);
@@ -336,6 +279,7 @@ g_ir_node_free (GIrNode *node)
        
        g_free (node->name);
        g_ir_node_free ((GIrNode *)field->type);
+       g_ir_node_free ((GIrNode *)field->callback);
       }
       break;
 
@@ -347,7 +291,9 @@ g_ir_node_free (GIrNode *node)
        g_free (node->name);
        g_free (iface->gtype_name);
        g_free (iface->gtype_init);
-       
+
+
+       g_free (iface->glib_type_struct);
        g_free (iface->parent);
 
        for (l = iface->interfaces; l; l = l->next)
@@ -401,6 +347,9 @@ g_ir_node_free (GIrNode *node)
        GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
 
        g_free (node->name);
+       g_free (struct_->gtype_name);
+       g_free (struct_->gtype_init);
+
        for (l = struct_->members; l; l = l->next)
          g_ir_node_free ((GIrNode *)l->data);
        g_list_free (struct_->members);
@@ -457,6 +406,8 @@ g_ir_node_free (GIrNode *node)
       break;
     } 
 
+  g_hash_table_destroy (node->attributes);
+
   g_free (node);
 }
 
@@ -470,19 +421,20 @@ g_ir_node_get_size (GIrNode *node)
   switch (node->type)
     {
     case G_IR_NODE_CALLBACK:
-      size = 12; 
+      size = sizeof (CallbackBlob);
       break;
 
     case G_IR_NODE_FUNCTION:
-      size = 16; 
+      size = sizeof (FunctionBlob);
       break;
 
     case G_IR_NODE_PARAM:
-      size = 12;
+      /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
+      size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
       break;
 
     case G_IR_NODE_TYPE:
-      size = 4;
+      size = sizeof (SimpleTypeBlob);
       break;
 
     case G_IR_NODE_OBJECT:
@@ -490,7 +442,7 @@ g_ir_node_get_size (GIrNode *node)
        GIrNodeInterface *iface = (GIrNodeInterface *)node;
 
        n = g_list_length (iface->interfaces);
-       size = 32 + 2 * (n + (n % 2));
+       size = sizeof (ObjectBlob) + 2 * (n + (n % 2));
 
        for (l = iface->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
@@ -502,7 +454,7 @@ g_ir_node_get_size (GIrNode *node)
        GIrNodeInterface *iface = (GIrNodeInterface *)node;
 
        n = g_list_length (iface->prerequisites);
-       size = 28 + 2 * (n + (n % 2));
+       size = sizeof (InterfaceBlob) + 2 * (n + (n % 2));
 
        for (l = iface->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
@@ -514,21 +466,21 @@ g_ir_node_get_size (GIrNode *node)
       {
        GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
        
-       size = 20;
+       size = sizeof (EnumBlob);
        for (l = enum_->values; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
       }
       break;
 
     case G_IR_NODE_VALUE:
-      size = 12;
+      size = sizeof (ValueBlob);
       break;
 
     case G_IR_NODE_STRUCT:
       {
        GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
 
-       size = 20;
+       size = sizeof (StructBlob);
        for (l = struct_->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
       }
@@ -538,34 +490,40 @@ g_ir_node_get_size (GIrNode *node)
       {
        GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
 
-       size = 20;
+       size = sizeof (StructBlob);
        for (l = boxed->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
       }
       break;
 
     case G_IR_NODE_PROPERTY:
-      size = 12;
+      size = sizeof (PropertyBlob);
       break;
 
     case G_IR_NODE_SIGNAL:
-      size = 12;
+      size = sizeof (SignalBlob);
       break;
 
     case G_IR_NODE_VFUNC:
-      size = 16;
+      size = sizeof (VFuncBlob);
       break;
 
     case G_IR_NODE_FIELD:
-      size = 12;
+      {
+       GIrNodeField *field = (GIrNodeField *)node;
+
+        size = sizeof (FieldBlob);
+        if (field->callback)
+          size += g_ir_node_get_size ((GIrNode *)field->callback);
+      }
       break;
 
     case G_IR_NODE_CONSTANT:
-      size = 20;
+      size = sizeof (ConstantBlob);
       break;
 
     case G_IR_NODE_ERROR_DOMAIN:
-      size = 16;
+      size = sizeof (ErrorDomainBlob);
       break;
 
     case G_IR_NODE_XREF:
@@ -576,7 +534,7 @@ g_ir_node_get_size (GIrNode *node)
       {
        GIrNodeUnion *union_ = (GIrNodeUnion *)node;
 
-       size = 28;
+       size = sizeof (UnionBlob);
        for (l = union_->members; l; l = l->next)
          size += g_ir_node_get_size ((GIrNode *)l->data);
        for (l = union_->discriminators; l; l = l->next)
@@ -596,9 +554,22 @@ g_ir_node_get_size (GIrNode *node)
   return size;
 }
 
+static void
+add_attribute_size (gpointer key, gpointer value, gpointer data)
+{
+  const gchar *key_str = key;
+  const gchar *value_str = value;
+  gint *size_p = data;
+
+  *size_p += sizeof (AttributeBlob);
+  *size_p += ALIGN_VALUE (strlen (key_str) + 1, 4);
+  *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4);
+}
+
 /* returns the full size of the blob including variable-size parts */
 static guint32
-g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
+g_ir_node_get_full_size_internal (GIrNode *parent,
+                                 GIrNode *node)
 {
   GList *l;
   gint size, n;
@@ -614,7 +585,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
     case G_IR_NODE_CALLBACK:
       {
        GIrNodeFunction *function = (GIrNodeFunction *)node;
-       size = 12; 
+       size = sizeof (CallbackBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        for (l = function->parameters; l; l = l->next)
          {
@@ -627,7 +598,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
     case G_IR_NODE_FUNCTION:
       {
        GIrNodeFunction *function = (GIrNodeFunction *)node;
-       size = 24;
+       size = sizeof (FunctionBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
        for (l = function->parameters; l; l = l->next)
@@ -640,7 +611,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeParam *param = (GIrNodeParam *)node;
        
-       size = 12;
+       /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
+       size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
        if (node->name)
          size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type);        
@@ -650,37 +622,36 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
     case G_IR_NODE_TYPE:
       {
        GIrNodeType *type = (GIrNodeType *)node;
-       if (type->tag < TYPE_TAG_ARRAY) 
-         size = 4;
-       else
+        size = sizeof (SimpleTypeBlob);
+        if (type->tag >= GI_TYPE_TAG_ARRAY)
          {
            g_debug ("node %p type tag '%s'", node,
-                    gi_type_tag_to_string (type->tag));
+                    g_type_tag_to_string (type->tag));
 
            switch (type->tag)
              {
-             case TYPE_TAG_ARRAY:
-               size = 4 + 4;
+             case GI_TYPE_TAG_ARRAY:
+               size = sizeof (ArrayTypeBlob);
                if (type->parameter_type1)
                  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
                break;
-             case TYPE_TAG_INTERFACE:
-               size = 4 + 4;
+             case GI_TYPE_TAG_INTERFACE:
+               size += sizeof (InterfaceTypeBlob);
                break;
-             case TYPE_TAG_LIST:
-             case TYPE_TAG_SLIST:
-               size = 4 + 4;
+             case GI_TYPE_TAG_GLIST:
+             case GI_TYPE_TAG_GSLIST:
+               size += sizeof (ParamTypeBlob);
                if (type->parameter_type1)
                  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
                break;
-             case TYPE_TAG_HASH:
-               size = 4 + 4 + 4;
+             case GI_TYPE_TAG_GHASH:
+               size += sizeof (ParamTypeBlob) * 2;
                if (type->parameter_type1)
                  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
                if (type->parameter_type2)
                  size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2);
                break;
-             case TYPE_TAG_ERROR:
+             case GI_TYPE_TAG_ERROR:
                {
                  gint n;
                  
@@ -689,7 +660,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
                  else
                    n = 0;
 
-                 size = 4 + 4 + 2 * (n + n % 2);
+                 size += sizeof (ErrorTypeBlob) + 2 * (n + n % 2);
                }
                break;
              default:
@@ -705,12 +676,15 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
        GIrNodeInterface *iface = (GIrNodeInterface *)node;
 
        n = g_list_length (iface->interfaces);
-       size = 32;
+       size = sizeof(ObjectBlob);
        if (iface->parent)
          size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
+        if (iface->glib_type_struct)
+          size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
-       size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
+       if (iface->gtype_init)
+         size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
        size += 2 * (n + (n % 2));
 
        for (l = iface->members; l; l = l->next)
@@ -723,7 +697,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
        GIrNodeInterface *iface = (GIrNodeInterface *)node;
 
        n = g_list_length (iface->prerequisites);
-       size = 28;
+       size = sizeof (InterfaceBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
        size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
@@ -739,7 +713,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
        
-       size = 20;
+       size = sizeof (EnumBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        if (enum_->gtype_name)
          {
@@ -754,7 +728,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
 
     case G_IR_NODE_VALUE:
       {
-       size = 12;
+       size = sizeof (ValueBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
       }
       break;
@@ -763,8 +737,12 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
 
-       size = 20;
+       size = sizeof (StructBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+       if (struct_->gtype_name)
+         size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
+       if (struct_->gtype_init)
+         size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
        for (l = struct_->members; l; l = l->next)
          size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
       }
@@ -774,7 +752,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
 
-       size = 20;
+       size = sizeof (StructBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        if (boxed->gtype_name)
          {
@@ -790,7 +768,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeProperty *prop = (GIrNodeProperty *)node;
        
-       size = 12;
+       size = sizeof (PropertyBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); 
       }
@@ -800,7 +778,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeSignal *signal = (GIrNodeSignal *)node;
 
-       size = 12;
+       size = sizeof (SignalBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        for (l = signal->parameters; l; l = l->next)
          size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
@@ -812,7 +790,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
 
-       size = 16;
+       size = sizeof (VFuncBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        for (l = vfunc->parameters; l; l = l->next)
          size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
@@ -824,9 +802,12 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeField *field = (GIrNodeField *)node;
 
-       size = 12;
+       size = sizeof (FieldBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
-       size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);        
+       if (field->callback)
+          size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->callback);
+       else
+          size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);
       }
       break;
 
@@ -834,7 +815,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeConstant *constant = (GIrNodeConstant *)node;
 
-       size = 20;
+       size = sizeof (ConstantBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        /* FIXME non-string values */
        size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
@@ -846,7 +827,7 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
 
-       size = 16;
+       size = sizeof (ErrorDomainBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
        size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
       }
@@ -866,8 +847,12 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       {
        GIrNodeUnion *union_ = (GIrNodeUnion *)node;
 
-       size = 28;
+       size = sizeof (UnionBlob);
        size += ALIGN_VALUE (strlen (node->name) + 1, 4);
+       if (union_->gtype_name)
+         size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
+       if (union_->gtype_init)
+         size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
        for (l = union_->members; l; l = l->next)
          size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
        for (l = union_->discriminators; l; l = l->next)
@@ -880,8 +865,11 @@ g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node)
       size = 0;
     }
 
-  g_debug ("node %p type '%s' full size %d", node,
-          g_ir_node_type_to_string (node->type), size);
+  g_debug ("node %s%s%s%p type '%s' full size %d",
+          node->name ? "'" : "",
+          node->name ? node->name : "",
+          node->name ? "' " : "",
+          node, g_ir_node_type_to_string (node->type), size);
 
   return size;
 }
@@ -892,6 +880,14 @@ g_ir_node_get_full_size (GIrNode *node)
   return g_ir_node_get_full_size_internal (NULL, node);
 }
 
+guint32
+g_ir_node_get_attribute_size (GIrNode *node)
+{
+  guint32 size = 0;
+  g_hash_table_foreach (node->attributes, add_attribute_size, &size);
+  return size;
+}
+
 int
 g_ir_node_cmp (GIrNode *node,
                GIrNode *other)
@@ -915,13 +911,32 @@ g_ir_node_can_have_member (GIrNode    *node)
     case G_IR_NODE_STRUCT:
     case G_IR_NODE_UNION:
       return TRUE;
+    /* list others individually rather than with default: so that compiler
+     * warns if new node types are added without adding them to the switch
+     */
+    case G_IR_NODE_INVALID:
+    case G_IR_NODE_FUNCTION:
+    case G_IR_NODE_CALLBACK:
+    case G_IR_NODE_ENUM:
+    case G_IR_NODE_FLAGS:
+    case G_IR_NODE_CONSTANT:
+    case G_IR_NODE_ERROR_DOMAIN:
+    case G_IR_NODE_PARAM:
+    case G_IR_NODE_TYPE:
+    case G_IR_NODE_PROPERTY:
+    case G_IR_NODE_SIGNAL:
+    case G_IR_NODE_VALUE:
+    case G_IR_NODE_VFUNC:
+    case G_IR_NODE_FIELD:
+    case G_IR_NODE_XREF:
+      return FALSE;
     };
   return FALSE;
 }
 
 void
 g_ir_node_add_member (GIrNode         *node,
-                      GIrNodeFunction *member)
+                     GIrNodeFunction *member)
 {
   g_return_if_fail (node != NULL);
   g_return_if_fail (member != NULL);
@@ -1012,7 +1027,7 @@ parse_boolean_value (const gchar *str)
 }
 
 static GIrNode *
-find_entry_node (GIrModule  *module,
+find_entry_node (GIrModule   *module,
                 GList       *modules,
                 const gchar *name,
                 guint16     *idx)
@@ -1024,6 +1039,9 @@ find_entry_node (GIrModule  *module,
   gint n_names;
   GIrNode *result = NULL;
 
+  g_assert (name != NULL);
+  g_assert (strlen (name) > 0);
+  
   names = g_strsplit (name, ".", 0);
   n_names = g_strv_length (names);
   if (n_names > 2)
@@ -1067,10 +1085,12 @@ find_entry_node (GIrModule  *module,
 
       result = node;
 
+      g_debug ("Creating XREF: %s %s", names[0], names[1]);
+
       goto out;
     }
 
-  g_warning ("Entry '%s' not found", name);
+  g_ir_module_fatal (module, 0, "Type reference '%s' not found", name);
 
  out:
 
@@ -1080,7 +1100,7 @@ find_entry_node (GIrModule  *module,
 }
 
 static guint16
-find_entry (GIrModule  *module,
+find_entry (GIrModule   *module,
            GList       *modules,
            const gchar *name)
 {
@@ -1091,10 +1111,120 @@ find_entry (GIrModule  *module,
   return idx;
 }
 
+static GIrNode *
+find_name_in_module (GIrModule   *module,
+                    const gchar *name)
+{
+  GList *l;
+
+  for (l = module->entries; l; l = l->next)
+    {
+      GIrNode *node = (GIrNode *)l->data;
+
+      if (strcmp (node->name, name) == 0)
+       return node;
+    }
+
+  return NULL;
+}
+
+gboolean
+g_ir_find_node (GIrModule  *module,
+               GList      *modules,
+               const char *name,
+               GIrNode   **node_out,
+               GIrModule **module_out)
+{
+  char **names = g_strsplit (name, ".", 0);
+  gint n_names = g_strv_length (names);
+  GIrNode *node = NULL;
+  GList *l;
+
+  if (n_names == 0)
+    {
+      g_warning ("Name can't be empty");
+      goto out;
+    }
+
+  if (n_names > 2)
+    {
+      g_warning ("Too many name parts in '%s'", name);
+      goto out;
+    }
+
+  if (n_names == 1)
+    {
+      *module_out = module;
+      node = find_name_in_module (module, names[0]);
+    }
+  else if (strcmp (names[0], module->name) == 0)
+    {
+      *module_out = module;
+      node = find_name_in_module (module, names[1]);
+    }
+  else
+    {
+      for (l = module->include_modules; l; l = l->next)
+       {
+         GIrModule *m = l->data;
+
+         if (strcmp (names[0], m->name) == 0)
+           {
+             *module_out = m;
+             node = find_name_in_module (m, names[1]);
+             goto out;
+           }
+       }
+
+      for (l = modules; l; l = l->next)
+       {
+         GIrModule *m = l->data;
+
+         if (strcmp (names[0], m->name) == 0)
+           {
+             *module_out = m;
+             node = find_name_in_module (m, names[1]);
+             goto out;
+           }
+       }
+    }
+
+ out:
+  g_strfreev (names);
+
+  *node_out = node;
+
+  return node != NULL;
+}
+
+static int
+get_index_of_member_type (GIrNodeInterface *node,
+                          GIrNodeTypeId type,
+                          const char *name)
+{
+  guint index = -1;
+  GList *l;
+
+  for (l = node->members; l; l = l->next)
+    {
+      GIrNode *node = l->data;
+
+      if (node->type != type)
+        continue;
+
+      index++;
+
+      if (strcmp (node->name, name) == 0)
+        break;
+    }
+
+  return index;
+}
+
 static void
-serialize_type (GIrModule   *module, 
+serialize_type (GIrModule    *module, 
                GList        *modules,
-               GIrNodeType *node, 
+               GIrNodeType  *node, 
                GString      *str)
 {
   gint i;
@@ -1109,6 +1239,8 @@ serialize_type (GIrModule   *module,
     "uint32", 
     "int64", 
     "uint64", 
+    "short",
+    "ushort",
     "int",
     "uint",
     "long",
@@ -1117,25 +1249,26 @@ serialize_type (GIrModule   *module,
     "size",
     "float", 
     "double",
+    "time_t",
+    "GType",
     "utf8", 
     "filename",
-    "string",
-    "sequence",
-    "any"
   };
   
-  if (node->tag < 20)
+  if (node->tag < GI_TYPE_TAG_ARRAY)
     {
-      g_string_append_printf (str, "%s%s", 
-                             basic[node->tag], node->is_pointer ? "*" : "");
+      g_string_append_printf (str, "%s%s", basic[node->tag],
+                             node->is_pointer ? "*" : "");
     }
-  else if (node->tag == 20)
+  else if (node->tag == GI_TYPE_TAG_ARRAY)
     {
       serialize_type (module, modules, node->parameter_type1, str);
       g_string_append (str, "[");
 
       if (node->has_length)
        g_string_append_printf (str, "length=%d", node->length);
+      else if (node->has_size)
+        g_string_append_printf (str, "fixed-size=%d", node->size);
       
       if (node->zero_terminated)
        g_string_append_printf (str, "%szero-terminated=1", 
@@ -1143,23 +1276,28 @@ serialize_type (GIrModule   *module,
       
       g_string_append (str, "]");
     }
-  else if (node->tag == 21)
+  else if (node->tag == GI_TYPE_TAG_INTERFACE)
     {
       GIrNode *iface;
       gchar *name;
 
       iface = find_entry_node (module, modules, node->interface, NULL);
       if (iface)
-       name = iface->name;
+        {
+          if (iface->type == G_IR_NODE_XREF)
+            g_string_append_printf (str, "%s.", ((GIrNodeXRef *)iface)->namespace);
+          name = iface->name;
+        }
       else
        {
          g_warning ("Interface for type reference %s not found", node->interface);
          name = node->interface;
        }
 
-      g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
+      g_string_append_printf (str, "%s%s", name,
+                             node->is_pointer ? "*" : "");
     }
-  else if (node->tag == 22)
+  else if (node->tag == GI_TYPE_TAG_GLIST)
     {
       g_string_append (str, "GList");
       if (node->parameter_type1)
@@ -1169,7 +1307,7 @@ serialize_type (GIrModule   *module,
          g_string_append (str, ">"); 
        }
     }
-  else if (node->tag == 23)
+  else if (node->tag == GI_TYPE_TAG_GSLIST)
     {
       g_string_append (str, "GSList");
       if (node->parameter_type1)
@@ -1179,7 +1317,7 @@ serialize_type (GIrModule   *module,
          g_string_append (str, ">"); 
        }
     }
-  else if (node->tag == 24)
+  else if (node->tag == GI_TYPE_TAG_GHASH)
     {
       g_string_append (str, "GHashTable<");
       if (node->parameter_type1)
@@ -1191,7 +1329,7 @@ serialize_type (GIrModule   *module,
          g_string_append (str, ">"); 
        }
     }
-  else if (node->tag == 25) 
+  else if (node->tag == GI_TYPE_TAG_ERROR)
     {
       g_string_append (str, "GError");
       if (node->errors)
@@ -1208,25 +1346,95 @@ serialize_type (GIrModule   *module,
     }
 }
 
+static void
+g_ir_node_build_members (GList         **members,
+                        GIrNodeTypeId   type,
+                        guint16        *count,
+                        GIrNode        *parent,
+                         GIrTypelibBuild *build,
+                        guint32        *offset,
+                        guint32        *offset2)
+{
+  GList *l = *members;
+
+  while (l)
+    {
+      GIrNode *member = (GIrNode *)l->data;
+      GList *next = l->next;
+
+      if (member->type == type)
+       {
+         (*count)++;
+         g_ir_node_build_typelib (member, parent, build, offset, offset2);
+         *members = g_list_delete_link (*members, l);
+       }
+      l = next;
+    }
+}
+
+static void
+g_ir_node_check_unhandled_members (GList         **members,
+                                  GIrNodeTypeId   container_type)
+{
+#if 0
+  if (*members)
+    {
+      GList *l;
+
+      for (l = *members; l; l = l->next)
+       {
+         GIrNode *member = (GIrNode *)l->data;
+         g_printerr ("Unhandled '%s' member '%s' type '%s'\n",
+                     g_ir_node_type_to_string (container_type),
+                     member->name,
+                     g_ir_node_type_to_string (member->type));
+       }
+
+      g_list_free (*members);
+      *members = NULL;
+
+      g_error ("Unhandled members. Aborting.");
+    }
+#else
+  g_list_free (*members);
+  *members = NULL;
+#endif
+}
+
 void
-g_ir_node_build_typelib (GIrNode   *node,
-                        GIrModule *module,
-                        GList      *modules,
-                        GHashTable *strings,
-                        GHashTable *types,
-                        guchar     *data,
-                        guint32    *offset,
-                        guint32    *offset2)
+g_ir_node_build_typelib (GIrNode         *node,
+                         GIrNode         *parent,
+                         GIrTypelibBuild *build,
+                         guint32         *offset,
+                         guint32         *offset2)
 {
+  GIrModule *module = build->module;
+  GList *modules = build->modules;
+  GHashTable *strings = build->strings;
+  GHashTable *types = build->types;
+  guchar *data = build->data;
   GList *l;
   guint32 old_offset = *offset;
   guint32 old_offset2 = *offset2;
 
   g_assert (node != NULL);
 
-  g_debug ("build_typelib (%s)",
+  g_debug ("build_typelib: %s%s(%s)",
+          node->name ? node->name : "",
+          node->name ? " " : "",
           g_ir_node_type_to_string (node->type));
 
+  g_ir_node_compute_offsets (node, module, modules);
+
+  /* We should only be building each node once.  If we do a typelib expansion, we also
+   * reset the offset in girmodule.c.
+   */
+  g_assert (node->offset == 0);
+  node->offset = *offset;
+  build->offset_ordered_nodes = g_list_prepend (build->offset_ordered_nodes, node);
+
+  build->n_attributes += g_hash_table_size (node->attributes);
+
   switch (node->type)
     {
     case G_IR_NODE_TYPE:
@@ -1234,17 +1442,17 @@ g_ir_node_build_typelib (GIrNode   *node,
        GIrNodeType *type = (GIrNodeType *)node;
        SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
 
-       *offset += 4;
+       *offset += sizeof (SimpleTypeBlob);
        
-       if (type->tag < TYPE_TAG_ARRAY ||
-           type->tag == TYPE_TAG_STRING ||
-           type->tag == TYPE_TAG_ANY)
+       if (type->tag < GI_TYPE_TAG_ARRAY ||
+           type->tag == GI_TYPE_TAG_UTF8 ||
+           type->tag == GI_TYPE_TAG_FILENAME)
          { 
-           blob->reserved = 0;
-           blob->reserved2 = 0;
-           blob->pointer = type->is_pointer;
-           blob->reserved3 = 0;
-           blob->tag = type->tag;
+           blob->flags.reserved = 0;
+           blob->flags.reserved2 = 0;
+           blob->flags.pointer = type->is_pointer;
+           blob->flags.reserved3 = 0;
+           blob->flags.tag = type->tag;
          }
        else 
          {
@@ -1260,18 +1468,18 @@ g_ir_node_build_typelib (GIrNode   *node,
            value = g_hash_table_lookup (types, s);
            if (value)
              {
-               blob->offset = GPOINTER_TO_INT (value);
+               blob->offset = GPOINTER_TO_UINT (value);
                g_free (s);
              }
            else
              {
                unique_types_count += 1;
-               g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
+               g_hash_table_insert (types, s, GUINT_TO_POINTER(*offset2));
                                     
                blob->offset = *offset2;
                switch (type->tag)
                  {
-                 case TYPE_TAG_ARRAY:
+                 case GI_TYPE_TAG_ARRAY:
                    {
                      ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
                      guint32 pos;
@@ -1281,22 +1489,27 @@ g_ir_node_build_typelib (GIrNode   *node,
                      array->tag = type->tag;
                      array->zero_terminated = type->zero_terminated;
                      array->has_length = type->has_length;
+                      array->has_size = type->has_size;
                      array->reserved2 = 0;
-                     array->length = type->length;
+                      if (array->has_length)
+                        array->dimensions.length = type->length;
+                      else if (array->has_size)
+                        array->dimensions.size  = type->size;
+                      else
+                        array->dimensions.length = -1;
                      
-                     pos = *offset2 + 4;
-                     *offset2 += 8;
+                     pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type);
+                     *offset2 += sizeof (ArrayTypeBlob);
                      
-                     g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
-                                              module, modules, strings, types, 
-                                              data, &pos, offset2);
+                     g_ir_node_build_typelib ((GIrNode *)type->parameter_type1,
+                                              node, build, &pos, offset2);
                    }
                    break;
                    
-                 case TYPE_TAG_INTERFACE:
+                 case GI_TYPE_TAG_INTERFACE:
                    {
                      InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
-                     *offset2 += 4;
+                     *offset2 += sizeof (InterfaceTypeBlob);
 
                      iface->pointer = type->is_pointer;
                      iface->reserved = 0;
@@ -1307,8 +1520,8 @@ g_ir_node_build_typelib (GIrNode   *node,
                    }
                    break;
                    
-                 case TYPE_TAG_LIST:
-                 case TYPE_TAG_SLIST:
+                 case GI_TYPE_TAG_GLIST:
+                 case GI_TYPE_TAG_GSLIST:
                    {
                      ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
                      guint32 pos;
@@ -1319,16 +1532,15 @@ g_ir_node_build_typelib (GIrNode   *node,
                      param->reserved2 = 0;
                      param->n_types = 1;
                      
-                     pos = *offset2 + 4;
-                     *offset2 += 8;
+                     pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
+                     *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob);
                      
                      g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
-                                              module, modules, strings, types,
-                                              data, &pos, offset2);
+                                              node, build, &pos, offset2);
                    }
                    break;
                    
-                 case TYPE_TAG_HASH:
+                 case GI_TYPE_TAG_GHASH:
                    {
                      ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
                      guint32 pos;
@@ -1339,19 +1551,17 @@ g_ir_node_build_typelib (GIrNode   *node,
                      param->reserved2 = 0;
                      param->n_types = 2;
                      
-                     pos = *offset2 + 4;
-                     *offset2 += 12;
+                     pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
+                     *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2;
                      
                      g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
-                                              module, modules, strings, types, 
-                                              data, &pos, offset2);
+                                              node, build, &pos, offset2);
                      g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, 
-                                              module, modules, strings, types, 
-                                              data, &pos, offset2);
+                                              node, build, &pos, offset2);
                    }
                    break;
                    
-                 case TYPE_TAG_ERROR:
+                 case GI_TYPE_TAG_ERROR:
                    {
                      ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
                      gint i;
@@ -1365,7 +1575,8 @@ g_ir_node_build_typelib (GIrNode   *node,
                      else
                        blob->n_domains = 0;
                      
-                     *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
+                     *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains)
+                                             + 2 * blob->n_domains, 4);
                      for (i = 0; i < blob->n_domains; i++)
                        blob->domains[i] = find_entry (module, modules, type->errors[i]);
                    }
@@ -1386,18 +1597,33 @@ g_ir_node_build_typelib (GIrNode   *node,
        FieldBlob *blob;
 
        blob = (FieldBlob *)&data[*offset];
-       *offset += 8;
 
        blob->name = write_string (node->name, strings, data, offset2);
        blob->readable = field->readable;
        blob->writable = field->writable;
        blob->reserved = 0;
        blob->bits = 0;
-       blob->struct_offset = field->offset;
-
-        g_ir_node_build_typelib ((GIrNode *)field->type, 
-                                module, modules, strings, types,
-                                data, offset, offset2);
+       if (field->offset >= 0)
+         blob->struct_offset = field->offset;
+       else
+         blob->struct_offset = 0xFFFF; /* mark as unknown */
+
+        if (field->callback)
+          {
+            blob->has_embedded_type = TRUE;
+            blob->type.offset = GI_INFO_TYPE_CALLBACK;
+           *offset += sizeof (FieldBlob);
+            g_ir_node_build_typelib ((GIrNode *)field->callback,
+                                    node, build, offset, offset2);
+          }
+        else
+          {
+            blob->has_embedded_type = FALSE;
+            /* We handle the size member specially below, so subtract it */
+           *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
+            g_ir_node_build_typelib ((GIrNode *)field->type,
+                                    node, build, offset, offset2);
+          }
       }
       break;
 
@@ -1405,7 +1631,8 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        GIrNodeProperty *prop = (GIrNodeProperty *)node;
        PropertyBlob *blob = (PropertyBlob *)&data[*offset];
-       *offset += 8;
+        /* We handle the size member specially below, so subtract it */
+       *offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob);
 
        blob->name = write_string (node->name, strings, data, offset2);
        blob->deprecated = prop->deprecated;
@@ -1416,8 +1643,7 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->reserved = 0;
 
         g_ir_node_build_typelib ((GIrNode *)prop->type, 
-                                module, modules, strings, types,
-                                data, offset, offset2);
+                                node, build, offset, offset2);
       }
       break;
 
@@ -1432,26 +1658,28 @@ g_ir_node_build_typelib (GIrNode   *node,
        signature = *offset2;
        n = g_list_length (function->parameters);
 
-       *offset += 16;
-       *offset2 += 8 + n * 12;
+       *offset += sizeof (FunctionBlob);
+       *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
 
        blob->blob_type = BLOB_TYPE_FUNCTION;
        blob->deprecated = function->deprecated;
+        blob->is_static = !function->is_method;
        blob->setter = function->is_setter;
        blob->getter = function->is_getter;
        blob->constructor = function->is_constructor;
        blob->wraps_vfunc = function->wraps_vfunc;
-       blob->reserved = 0;
+       blob->throws = function->throws;
        blob->index = 0;
        blob->name = write_string (node->name, strings, data, offset2);
        blob->symbol = write_string (function->symbol, strings, data, offset2);
        blob->signature = signature;
-       
+
+       g_debug ("building function '%s'", function->symbol);
+
         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
-                                module, modules, strings, types,
-                                data, &signature, offset2);
+                                node, build, &signature, offset2);
 
-       blob2->may_return_null = function->result->null_ok;
+       blob2->may_return_null = function->result->allow_none;
        blob2->caller_owns_return_value = function->result->transfer;
        blob2->caller_owns_return_container = function->result->shallow_transfer;
        blob2->reserved = 0;
@@ -1463,10 +1691,9 @@ g_ir_node_build_typelib (GIrNode   *node,
          {
            GIrNode *param = (GIrNode *)l->data;
 
-           g_ir_node_build_typelib (param, 
-                                    module, modules, strings, types,
-                                    data, &signature, offset2);
+           g_ir_node_build_typelib (param, node, build, &signature, offset2);
          }
+
       }
       break;
 
@@ -1481,8 +1708,8 @@ g_ir_node_build_typelib (GIrNode   *node,
        signature = *offset2;
        n = g_list_length (function->parameters);
 
-       *offset += 12;
-       *offset2 += 8 + n * 12;
+       *offset += sizeof (CallbackBlob);
+       *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
 
        blob->blob_type = BLOB_TYPE_CALLBACK;
        blob->deprecated = function->deprecated;
@@ -1491,10 +1718,9 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->signature = signature;
        
         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
-                                module, modules, strings, types,
-                                data, &signature, offset2);
+                                node, build, &signature, offset2);
 
-       blob2->may_return_null = function->result->null_ok;
+       blob2->may_return_null = function->result->allow_none;
        blob2->caller_owns_return_value = function->result->transfer;
        blob2->caller_owns_return_container = function->result->shallow_transfer;
        blob2->reserved = 0;
@@ -1506,9 +1732,7 @@ g_ir_node_build_typelib (GIrNode   *node,
          {
            GIrNode *param = (GIrNode *)l->data;
 
-           g_ir_node_build_typelib (param, 
-                                    module, modules, strings, types,
-                                    data, &signature, offset2);
+           g_ir_node_build_typelib (param, node, build, &signature, offset2);
          }
       }
       break;
@@ -1524,8 +1748,8 @@ g_ir_node_build_typelib (GIrNode   *node,
        signature = *offset2;
        n = g_list_length (signal->parameters);
 
-       *offset += 12;
-       *offset2 += 8 + n * 12;
+       *offset += sizeof (SignalBlob);
+       *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
 
        blob->deprecated = signal->deprecated;
        blob->run_first = signal->run_first;
@@ -1543,10 +1767,9 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->signature = signature;
        
         g_ir_node_build_typelib ((GIrNode *)signal->result->type, 
-                                module, modules, strings, types,
-                                data, &signature, offset2);
+                                node, build, &signature, offset2);
 
-       blob2->may_return_null = signal->result->null_ok;
+       blob2->may_return_null = signal->result->allow_none;
        blob2->caller_owns_return_value = signal->result->transfer;
        blob2->caller_owns_return_container = signal->result->shallow_transfer;
        blob2->reserved = 0;
@@ -1558,8 +1781,7 @@ g_ir_node_build_typelib (GIrNode   *node,
          {
            GIrNode *param = (GIrNode *)l->data;
 
-           g_ir_node_build_typelib (param, module, modules, strings, types,
-                                    data, &signature, offset2);
+           g_ir_node_build_typelib (param, node, build, &signature, offset2);
          }
       }
       break;
@@ -1575,8 +1797,8 @@ g_ir_node_build_typelib (GIrNode   *node,
        signature = *offset2;
        n = g_list_length (vfunc->parameters);
 
-       *offset += 16;
-       *offset2 += 8 + n * 12;
+       *offset += sizeof (VFuncBlob);
+       *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
 
        blob->name = write_string (node->name, strings, data, offset2);
        blob->must_chain_up = 0; /* FIXME */
@@ -1585,15 +1807,26 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->class_closure = 0; /* FIXME */
        blob->reserved = 0;
 
+       if (vfunc->invoker)
+         {
+           int index = get_index_of_member_type ((GIrNodeInterface*)parent, G_IR_NODE_FUNCTION, vfunc->invoker);
+           if (index == -1)
+             {
+               g_error ("Unknown member function %s for vfunc %s", vfunc->invoker, node->name);
+             }
+            blob->invoker = (guint) index;
+         }
+       else
+         blob->invoker = 0x3ff; /* max of 10 bits */
+
        blob->struct_offset = vfunc->offset;
        blob->reserved2 = 0;
        blob->signature = signature;
        
         g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, 
-                                module, modules, strings, types,
-                                data, &signature, offset2);
+                                node, build, &signature, offset2);
 
-       blob2->may_return_null = vfunc->result->null_ok;
+       blob2->may_return_null = vfunc->result->allow_none;
        blob2->caller_owns_return_value = vfunc->result->transfer;
        blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
        blob2->reserved = 0;
@@ -1605,8 +1838,7 @@ g_ir_node_build_typelib (GIrNode   *node,
          {
            GIrNode *param = (GIrNode *)l->data;
 
-           g_ir_node_build_typelib (param, module, modules, strings, 
-                                    types, data, &signature, offset2);
+           g_ir_node_build_typelib (param, node, build, &signature, offset2);
          }
       }
       break;
@@ -1615,22 +1847,27 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        ArgBlob *blob = (ArgBlob *)&data[*offset];
        GIrNodeParam *param = (GIrNodeParam *)node;
-       
-       *offset += 8;
+
+       /* The offset for this one is smaller than the struct because
+        * we recursively build the simple type inline here below.
+        */
+       *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
 
        blob->name = write_string (node->name, strings, data, offset2);
        blob->in = param->in;
        blob->out = param->out;
        blob->dipper = param->dipper;
-       blob->null_ok = param->null_ok;
+       blob->allow_none = param->allow_none;
        blob->optional = param->optional;
        blob->transfer_ownership = param->transfer;
        blob->transfer_container_ownership = param->shallow_transfer;
        blob->return_value = param->retval;
+        blob->scope = param->scope;
        blob->reserved = 0;
-
-        g_ir_node_build_typelib ((GIrNode *)param->type, module, modules, 
-                                strings, types, data, offset, offset2);
+        blob->closure = param->closure;
+        blob->destroy = param->destroy;
+        
+        g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2);
       }
       break;
 
@@ -1638,42 +1875,45 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        StructBlob *blob = (StructBlob *)&data[*offset];
        GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
+       GList *members;
        
        blob->blob_type = BLOB_TYPE_STRUCT;
        blob->deprecated = struct_->deprecated;
-       blob->unregistered = TRUE;
+       blob->is_gtype_struct = struct_->is_gtype_struct;
        blob->reserved = 0;
        blob->name = write_string (node->name, strings, data, offset2);
-       blob->gtype_name = 0;
-       blob->gtype_init = 0;
+       blob->alignment = struct_->alignment;
+       blob->size = struct_->size;
+
+       if (struct_->gtype_name)
+         {
+           blob->unregistered = FALSE;
+           blob->gtype_name = write_string (struct_->gtype_name, strings, data, offset2);
+           blob->gtype_init = write_string (struct_->gtype_init, strings, data, offset2);
+         }
+       else
+         {
+           blob->unregistered = TRUE;
+           blob->gtype_name = 0;
+           blob->gtype_init = 0;
+         }
 
        blob->n_fields = 0;
        blob->n_methods = 0;
 
-       *offset += 20; 
-       for (l = struct_->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       *offset += sizeof (StructBlob);
 
-           if (member->type == G_IR_NODE_FIELD)
-             {
-               blob->n_fields++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       members = g_list_copy (struct_->members);
 
-       for (l = struct_->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-           
-           if (member->type == G_IR_NODE_FUNCTION)
-             {
-               blob->n_methods++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
+                                node, build, offset, offset2);
+
+       g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
+                                node, build, offset, offset2);
+
+       g_ir_node_check_unhandled_members (&members, node->type);
+
+       g_assert (members == NULL);
       }
       break;
 
@@ -1681,6 +1921,7 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        StructBlob *blob = (StructBlob *)&data[*offset];
        GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
+       GList *members;
 
        blob->blob_type = BLOB_TYPE_BOXED;
        blob->deprecated = boxed->deprecated;
@@ -1689,34 +1930,25 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->name = write_string (node->name, strings, data, offset2);
        blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
        blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
+       blob->alignment = boxed->alignment;
+       blob->size = boxed->size;
 
        blob->n_fields = 0;
        blob->n_methods = 0;
 
-       *offset += 20; 
-       for (l = boxed->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       *offset += sizeof (StructBlob);
 
-           if (member->type == G_IR_NODE_FIELD)
-             {
-               blob->n_fields++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       members = g_list_copy (boxed->members);
 
-       for (l = boxed->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
+                                node, build, offset, offset2);
 
-           if (member->type == G_IR_NODE_FUNCTION)
-             {
-               blob->n_methods++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
+                                node, build, offset, offset2);
+
+       g_ir_node_check_unhandled_members (&members, node->type);
+
+       g_assert (members == NULL);
       }
       break;
 
@@ -1724,11 +1956,14 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        UnionBlob *blob = (UnionBlob *)&data[*offset];
        GIrNodeUnion *union_ = (GIrNodeUnion *)node;
+       GList *members;
 
        blob->blob_type = BLOB_TYPE_UNION;
        blob->deprecated = union_->deprecated;
        blob->reserved = 0;
        blob->name = write_string (node->name, strings, data, offset2);
+       blob->alignment = union_->alignment;
+       blob->size = union_->size;
        if (union_->gtype_name)
          {
            blob->unregistered = FALSE;
@@ -1747,45 +1982,33 @@ g_ir_node_build_typelib (GIrNode   *node,
 
        blob->discriminator_offset = union_->discriminator_offset;
 
+       /* We don't support Union discriminators right now. */
+       /*
        if (union_->discriminator_type)
          {
-           *offset += 24;
+           *offset += 28;
            blob->discriminated = TRUE;
            g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, 
-                                    module, modules, strings, types,
-                                    data, offset, offset2);
+                                    build, offset, offset2);
          }
-       else 
+       else
          {
-           *offset += 28;
-           blob->discriminated = FALSE;
-           blob->discriminator_type.offset = 0;
-         }
+        */
+       *offset += sizeof (UnionBlob);
+       blob->discriminated = FALSE;
+       blob->discriminator_type.offset = 0;
        
-       
-       for (l = union_->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       members = g_list_copy (union_->members);
 
-           if (member->type == G_IR_NODE_FIELD)
-             {
-               blob->n_fields++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
+                                node, build, offset, offset2);
 
-       for (l = union_->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions,
+                                node, build, offset, offset2);
 
-           if (member->type == G_IR_NODE_FUNCTION)
-             {
-               blob->n_functions++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_check_unhandled_members (&members, node->type);
+
+       g_assert (members == NULL);
 
        if (union_->discriminator_type)
          {
@@ -1793,8 +2016,7 @@ g_ir_node_build_typelib (GIrNode   *node,
              {
                GIrNode *member = (GIrNode *)l->data;
                
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
+               g_ir_node_build_typelib (member, node, build, offset, offset2);
              }
          }
       }
@@ -1806,8 +2028,8 @@ g_ir_node_build_typelib (GIrNode   *node,
        EnumBlob *blob = (EnumBlob *)&data[*offset];
        GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
 
-       *offset += 20
-       
+       *offset += sizeof (EnumBlob)
+
        if (node->type == G_IR_NODE_ENUM)
          blob->blob_type = BLOB_TYPE_ENUM;
        else
@@ -1815,6 +2037,7 @@ g_ir_node_build_typelib (GIrNode   *node,
          
        blob->deprecated = enum_->deprecated;
        blob->reserved = 0;
+       blob->storage_type = enum_->storage_type;
        blob->name = write_string (node->name, strings, data, offset2);
        if (enum_->gtype_name)
          {
@@ -1837,8 +2060,7 @@ g_ir_node_build_typelib (GIrNode   *node,
            GIrNode *value = (GIrNode *)l->data;
 
            blob->n_values++;
-           g_ir_node_build_typelib (value, module, modules, strings, types,
-                                    data, offset, offset2);
+           g_ir_node_build_typelib (value, node, build, offset, offset2);
          }
       }
       break;
@@ -1847,8 +2069,10 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        ObjectBlob *blob = (ObjectBlob *)&data[*offset];
        GIrNodeInterface *object = (GIrNodeInterface *)node;
+       GList *members;
 
        blob->blob_type = BLOB_TYPE_OBJECT;
+       blob->abstract = object->abstract;
        blob->deprecated = object->deprecated;
        blob->reserved = 0;
        blob->name = write_string (node->name, strings, data, offset2);
@@ -1858,6 +2082,10 @@ g_ir_node_build_typelib (GIrNode   *node,
          blob->parent = find_entry (module, modules, object->parent);
        else
          blob->parent = 0;
+       if (object->glib_type_struct)
+         blob->gtype_struct = find_entry (module, modules, object->glib_type_struct);
+       else
+         blob->gtype_struct = 0;
 
        blob->n_interfaces = 0;
        blob->n_fields = 0;
@@ -1867,7 +2095,7 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->n_vfuncs = 0;
        blob->n_constants = 0;
        
-       *offset += 32;
+       *offset += sizeof(ObjectBlob);
        for (l = object->interfaces; l; l = l->next)
          {
            blob->n_interfaces++;
@@ -1875,83 +2103,35 @@ g_ir_node_build_typelib (GIrNode   *node,
            *offset += 2;
          }
        
-       *offset = ALIGN_VALUE (*offset, 4);
-       for (l = object->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-
-           if (member->type == G_IR_NODE_FIELD)
-             {
-               blob->n_fields++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       members = g_list_copy (object->members);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = object->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-
-           if (member->type == G_IR_NODE_PROPERTY)
-             {
-               blob->n_properties++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
+                                node, build, offset, offset2);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = object->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-
-           if (member->type == G_IR_NODE_FUNCTION)
-             {
-               blob->n_methods++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
+                                node, build, offset, offset2);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = object->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-
-           if (member->type == G_IR_NODE_SIGNAL)
-             {
-               blob->n_signals++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
+                                node, build, offset, offset2);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = object->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
+                                node, build, offset, offset2);
 
-           if (member->type == G_IR_NODE_VFUNC)
-             {
-               blob->n_vfuncs++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       *offset = ALIGN_VALUE (*offset, 4);
+       g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
+                                node, build, offset, offset2);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = object->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
+                                node, build, offset, offset2);
 
-           if (member->type == G_IR_NODE_CONSTANT)
-             {
-               blob->n_constants++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_check_unhandled_members (&members, node->type);
+
+       g_assert (members == NULL);
       }
       break;
 
@@ -1959,6 +2139,7 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
        GIrNodeInterface *iface = (GIrNodeInterface *)node;
+       GList *members;
 
        blob->blob_type = BLOB_TYPE_INTERFACE;
        blob->deprecated = iface->deprecated;
@@ -1966,6 +2147,10 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->name = write_string (node->name, strings, data, offset2);
        blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
        blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
+       if (iface->glib_type_struct)
+         blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct);
+       else
+         blob->gtype_struct = 0;
        blob->n_prerequisites = 0;
        blob->n_properties = 0;
        blob->n_methods = 0;
@@ -1973,7 +2158,7 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->n_vfuncs = 0;
        blob->n_constants = 0;
        
-       *offset += 28;
+       *offset += sizeof (InterfaceBlob);
        for (l = iface->prerequisites; l; l = l->next)
          {
            blob->n_prerequisites++;
@@ -1981,70 +2166,31 @@ g_ir_node_build_typelib (GIrNode   *node,
            *offset += 2;
          }
        
-       *offset = ALIGN_VALUE (*offset, 4);
-       for (l = iface->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-
-           if (member->type == G_IR_NODE_PROPERTY)
-             {
-               blob->n_properties++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       members = g_list_copy (iface->members);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = iface->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-
-           if (member->type == G_IR_NODE_FUNCTION)
-             {
-               blob->n_methods++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
+                                node, build, offset, offset2);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = iface->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
-
-           if (member->type == G_IR_NODE_SIGNAL)
-             {
-               blob->n_signals++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
+                                node, build, offset, offset2);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = iface->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
+                                node, build, offset, offset2);
 
-           if (member->type == G_IR_NODE_VFUNC)
-             {
-               blob->n_vfuncs++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       *offset = ALIGN_VALUE (*offset, 4);
+       g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
+                                node, build, offset, offset2);
 
        *offset = ALIGN_VALUE (*offset, 4);
-       for (l = iface->members; l; l = l->next)
-         {
-           GIrNode *member = (GIrNode *)l->data;
+       g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
+                                node, build, offset, offset2);
 
-           if (member->type == G_IR_NODE_CONSTANT)
-             {
-               blob->n_constants++;
-               g_ir_node_build_typelib (member, module, modules, strings, 
-                                        types, data, offset, offset2);
-             }
-         }
+       g_ir_node_check_unhandled_members (&members, node->type);
+
+       g_assert (members == NULL);
       }
       break;
 
@@ -2053,7 +2199,7 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        GIrNodeValue *value = (GIrNodeValue *)node;
        ValueBlob *blob = (ValueBlob *)&data[*offset];
-       *offset += 12;
+       *offset += sizeof (ValueBlob);
 
        blob->deprecated = value->deprecated;
        blob->reserved = 0;
@@ -2066,7 +2212,7 @@ g_ir_node_build_typelib (GIrNode   *node,
       {
        GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
        ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
-       *offset += 16;
+       *offset += sizeof (ErrorDomainBlob);
 
        blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
        blob->deprecated = domain->deprecated;
@@ -2084,8 +2230,8 @@ g_ir_node_build_typelib (GIrNode   *node,
        ConstantBlob *blob = (ConstantBlob *)&data[*offset];
        guint32 pos;
 
-       pos = *offset + 8;
-       *offset += 20;
+       pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type);
+       *offset += sizeof (ConstantBlob);
 
        blob->blob_type = BLOB_TYPE_CONSTANT;
        blob->deprecated = constant->deprecated;
@@ -2095,90 +2241,102 @@ g_ir_node_build_typelib (GIrNode   *node,
        blob->offset = *offset2;
        switch (constant->type->tag)
          {
-         case TYPE_TAG_BOOLEAN:
+         case GI_TYPE_TAG_BOOLEAN:
            blob->size = 4;
            *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
            break;
-           case TYPE_TAG_INT8:
+           case GI_TYPE_TAG_INT8:
            blob->size = 1;
              *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
            break;
-         case TYPE_TAG_UINT8:
+         case GI_TYPE_TAG_UINT8:
            blob->size = 1;
            *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
            break;
-         case TYPE_TAG_INT16:
+         case GI_TYPE_TAG_INT16:
            blob->size = 2;
            *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
            break;
-         case TYPE_TAG_UINT16:
+         case GI_TYPE_TAG_UINT16:
            blob->size = 2;
            *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
            break;
-         case TYPE_TAG_INT32:
+         case GI_TYPE_TAG_INT32:
            blob->size = 4;
            *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
            break;
-         case TYPE_TAG_UINT32:
+         case GI_TYPE_TAG_UINT32:
            blob->size = 4;
            *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
            break;
-         case TYPE_TAG_INT64:
+         case GI_TYPE_TAG_INT64:
            blob->size = 8;
            *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
            break;
-         case TYPE_TAG_UINT64:
+         case GI_TYPE_TAG_UINT64:
            blob->size = 8;
            *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
            break;
-         case TYPE_TAG_INT:
+         case GI_TYPE_TAG_SHORT:
+           blob->size = sizeof (gshort);
+           *(gshort*)&data[blob->offset] = (gshort) parse_int_value (constant->value);
+           break;
+         case GI_TYPE_TAG_USHORT:
+           blob->size = sizeof (gushort);
+           *(gushort*)&data[blob->offset] = (gushort) parse_uint_value (constant->value);
+           break;
+         case GI_TYPE_TAG_INT:
            blob->size = sizeof (gint);
            *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
            break;
-         case TYPE_TAG_UINT:
+         case GI_TYPE_TAG_UINT:
            blob->size = sizeof (guint);
            *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
            break;
-         case TYPE_TAG_SSIZE: /* FIXME */
-         case TYPE_TAG_LONG:
+         case GI_TYPE_TAG_SSIZE: /* FIXME */
+         case GI_TYPE_TAG_LONG:
            blob->size = sizeof (glong);
            *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
            break;
-         case TYPE_TAG_SIZE: /* FIXME */
-         case TYPE_TAG_ULONG:
+         case GI_TYPE_TAG_SIZE: /* FIXME */
+         case GI_TYPE_TAG_TIME_T: 
+         case GI_TYPE_TAG_ULONG:
            blob->size = sizeof (gulong);
            *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
            break;
-         case TYPE_TAG_FLOAT:
+         case GI_TYPE_TAG_FLOAT:
            blob->size = sizeof (gfloat);
            *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
            break;
-         case TYPE_TAG_DOUBLE:
+         case GI_TYPE_TAG_DOUBLE:
            blob->size = sizeof (gdouble);
            *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
            break;
-         case TYPE_TAG_UTF8:
-         case TYPE_TAG_FILENAME:
+         case GI_TYPE_TAG_UTF8:
+         case GI_TYPE_TAG_FILENAME:
            blob->size = strlen (constant->value) + 1;
            memcpy (&data[blob->offset], constant->value, blob->size);
            break;
          }
        *offset2 += ALIGN_VALUE (blob->size, 4);
        
-       g_ir_node_build_typelib ((GIrNode *)constant->type, module, modules, 
-                                strings, types, data, &pos, offset2);
+       g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2);
       }
       break;
     default:
       g_assert_not_reached ();
     }
   
-  g_debug ("node %p type '%s', offset %d -> %d, offset2 %d -> %d",
+  g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d",
+          node->name ? "'" : "",
+          node->name ? node->name : "",
+          node->name ? "' " : "",
           node, g_ir_node_type_to_string (node->type),
           old_offset, *offset, old_offset2, *offset2);
 
   if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node))
-    g_error ("exceeding space reservation !!");
+    g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
+             *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node));
 }
 
 /* if str is already in the pool, return previous location, otherwise write str
@@ -2200,12 +2358,12 @@ write_string (const gchar *str,
   value = g_hash_table_lookup (strings, str);
   
   if (value)
-    return GPOINTER_TO_INT (value);
+    return GPOINTER_TO_UINT (value);
 
   unique_string_count += 1;
   unique_string_size += strlen (str);
 
-  g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
+  g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset));
 
   start = *offset;
   *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);