[g-ir-compiler] Slightly less lame error messages
[gnome.gobject-introspection] / girepository / girnode.c
1 /* GObject introspection: Typelib creation
2  *
3  * Copyright (C) 2005 Matthias Clasen
4  * Copyright (C) 2008,2009 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "girmodule.h"
27 #include "girnode.h"
28 #include "gtypelib.h"
29
30 static gulong string_count = 0;
31 static gulong unique_string_count = 0;
32 static gulong string_size = 0;
33 static gulong unique_string_size = 0;
34 static gulong types_count = 0;
35 static gulong unique_types_count = 0;
36
37 void
38 _g_irnode_init_stats (void)
39 {
40   string_count = 0;
41   unique_string_count = 0;
42   string_size = 0;
43   unique_string_size = 0;
44   types_count = 0;
45   unique_types_count = 0;
46 }
47
48 void
49 _g_irnode_dump_stats (void)
50 {
51   g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
52              unique_string_count, string_count, unique_string_size, string_size);
53   g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
54 }
55
56 #define ALIGN_VALUE(this, boundary) \
57   (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
58
59
60 const gchar *
61 g_ir_node_type_to_string (GIrNodeTypeId type)
62 {
63   switch (type)
64     {
65     case G_IR_NODE_FUNCTION:
66       return "function";
67     case G_IR_NODE_CALLBACK:
68       return "callback";
69     case G_IR_NODE_PARAM:
70       return "param";
71     case G_IR_NODE_TYPE:
72       return "type";
73     case G_IR_NODE_OBJECT:
74       return "object";
75     case G_IR_NODE_INTERFACE:
76       return "interface";
77     case G_IR_NODE_SIGNAL:
78       return "signal";
79     case G_IR_NODE_PROPERTY:
80       return "property";
81     case G_IR_NODE_VFUNC:
82       return "vfunc";
83     case G_IR_NODE_FIELD:
84       return "field";
85     case G_IR_NODE_ENUM:
86       return "enum";
87     case G_IR_NODE_FLAGS:
88       return "flags";
89     case G_IR_NODE_BOXED:
90       return "boxed";
91     case G_IR_NODE_STRUCT:
92       return "struct";
93     case G_IR_NODE_VALUE:
94       return "value";
95     case G_IR_NODE_CONSTANT:
96       return "constant";
97     case G_IR_NODE_ERROR_DOMAIN:
98       return "error-domain";
99     case G_IR_NODE_XREF:
100       return "xref";
101     case G_IR_NODE_UNION:
102       return "union";
103     default:
104       return "unknown";
105     }
106 }
107
108 GIrNode *
109 g_ir_node_new (GIrNodeTypeId type)
110 {
111   GIrNode *node = NULL;
112
113   switch (type)
114     {
115    case G_IR_NODE_FUNCTION:
116    case G_IR_NODE_CALLBACK:
117       node = g_malloc0 (sizeof (GIrNodeFunction));
118       break;
119
120    case G_IR_NODE_PARAM:
121       node = g_malloc0 (sizeof (GIrNodeParam));
122       break;
123
124    case G_IR_NODE_TYPE:
125       node = g_malloc0 (sizeof (GIrNodeType));
126       break;
127
128     case G_IR_NODE_OBJECT:
129     case G_IR_NODE_INTERFACE:
130       node = g_malloc0 (sizeof (GIrNodeInterface));
131       break;
132
133     case G_IR_NODE_SIGNAL:
134       node = g_malloc0 (sizeof (GIrNodeSignal));
135       break;
136
137     case G_IR_NODE_PROPERTY:
138       node = g_malloc0 (sizeof (GIrNodeProperty));
139       break;
140
141     case G_IR_NODE_VFUNC:
142       node = g_malloc0 (sizeof (GIrNodeFunction));
143       break;
144
145     case G_IR_NODE_FIELD:
146       node = g_malloc0 (sizeof (GIrNodeField));
147       break;
148
149     case G_IR_NODE_ENUM:
150     case G_IR_NODE_FLAGS:
151       node = g_malloc0 (sizeof (GIrNodeEnum));
152       break;
153
154     case G_IR_NODE_BOXED:
155       node = g_malloc0 (sizeof (GIrNodeBoxed));
156       break;
157
158     case G_IR_NODE_STRUCT:
159       node = g_malloc0 (sizeof (GIrNodeStruct));
160       break;
161
162     case G_IR_NODE_VALUE:
163       node = g_malloc0 (sizeof (GIrNodeValue));
164       break;
165
166     case G_IR_NODE_CONSTANT:
167       node = g_malloc0 (sizeof (GIrNodeConstant));
168       break;
169
170     case G_IR_NODE_ERROR_DOMAIN:
171       node = g_malloc0 (sizeof (GIrNodeErrorDomain));
172       break;
173
174     case G_IR_NODE_XREF:
175       node = g_malloc0 (sizeof (GIrNodeXRef));
176       break;
177
178     case G_IR_NODE_UNION:
179       node = g_malloc0 (sizeof (GIrNodeUnion));
180       break;
181
182     default:
183       g_error ("Unhandled node type %d\n", type);
184       break;
185     }
186
187   node->type = type;
188   node->offset = 0;
189   node->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
190                                             g_free, g_free);
191
192   return node;
193 }
194
195 void
196 g_ir_node_free (GIrNode *node)
197 {
198   GList *l;
199
200   if (node == NULL)
201     return;
202
203   switch (node->type)
204     {
205     case G_IR_NODE_FUNCTION:
206     case G_IR_NODE_CALLBACK:
207       {
208         GIrNodeFunction *function = (GIrNodeFunction *)node;
209         
210         g_free (node->name);
211         g_free (function->symbol);
212         g_ir_node_free ((GIrNode *)function->result);
213         for (l = function->parameters; l; l = l->next)
214           g_ir_node_free ((GIrNode *)l->data);
215         g_list_free (function->parameters);
216       }
217       break;
218
219     case G_IR_NODE_TYPE:
220       {
221         GIrNodeType *type = (GIrNodeType *)node;
222         
223         g_free (node->name);
224         g_ir_node_free ((GIrNode *)type->parameter_type1);
225         g_ir_node_free ((GIrNode *)type->parameter_type2);
226
227         g_free (type->interface);
228         g_strfreev (type->errors);
229
230       }
231       break;
232
233     case G_IR_NODE_PARAM:
234       {
235         GIrNodeParam *param = (GIrNodeParam *)node;
236         
237         g_free (node->name);
238         g_ir_node_free ((GIrNode *)param->type);
239       }
240       break;
241
242     case G_IR_NODE_PROPERTY:
243       {
244         GIrNodeProperty *property = (GIrNodeProperty *)node;
245         
246         g_free (node->name);
247         g_ir_node_free ((GIrNode *)property->type);
248       }
249       break;
250
251     case G_IR_NODE_SIGNAL:
252       {
253         GIrNodeSignal *signal = (GIrNodeSignal *)node;
254         
255         g_free (node->name);
256         for (l = signal->parameters; l; l = l->next)
257           g_ir_node_free ((GIrNode *)l->data);
258         g_list_free (signal->parameters);
259         g_ir_node_free ((GIrNode *)signal->result);
260       }
261       break;
262
263     case G_IR_NODE_VFUNC:
264       {
265         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
266         
267         g_free (node->name);
268         g_free (vfunc->invoker);
269         for (l = vfunc->parameters; l; l = l->next)
270           g_ir_node_free ((GIrNode *)l->data);
271         g_list_free (vfunc->parameters);
272         g_ir_node_free ((GIrNode *)vfunc->result);
273       }
274       break;
275
276     case G_IR_NODE_FIELD:
277       {
278         GIrNodeField *field = (GIrNodeField *)node;
279         
280         g_free (node->name);
281         g_ir_node_free ((GIrNode *)field->type);
282         g_ir_node_free ((GIrNode *)field->callback);
283       }
284       break;
285
286     case G_IR_NODE_OBJECT:
287     case G_IR_NODE_INTERFACE:
288       {
289         GIrNodeInterface *iface = (GIrNodeInterface *)node;
290         
291         g_free (node->name);
292         g_free (iface->gtype_name);
293         g_free (iface->gtype_init);
294
295
296         g_free (iface->glib_type_struct);
297         g_free (iface->parent);
298
299         for (l = iface->interfaces; l; l = l->next)
300           g_free ((GIrNode *)l->data);
301         g_list_free (iface->interfaces);
302
303         for (l = iface->members; l; l = l->next)
304           g_ir_node_free ((GIrNode *)l->data);
305         g_list_free (iface->members);
306
307       }
308       break;
309  
310     case G_IR_NODE_VALUE:
311       {
312         g_free (node->name);
313       }
314       break;
315
316     case G_IR_NODE_ENUM:
317     case G_IR_NODE_FLAGS:
318       {
319         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
320         
321         g_free (node->name);
322         g_free (enum_->gtype_name);
323         g_free (enum_->gtype_init);
324
325         for (l = enum_->values; l; l = l->next)
326           g_ir_node_free ((GIrNode *)l->data);
327         g_list_free (enum_->values);
328       }
329       break;
330
331     case G_IR_NODE_BOXED:
332       {
333         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
334         
335         g_free (node->name);
336         g_free (boxed->gtype_name);
337         g_free (boxed->gtype_init);
338
339         for (l = boxed->members; l; l = l->next)
340           g_ir_node_free ((GIrNode *)l->data);
341         g_list_free (boxed->members);
342       }
343       break;
344
345     case G_IR_NODE_STRUCT:
346       {
347         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
348
349         g_free (node->name);
350         g_free (struct_->gtype_name);
351         g_free (struct_->gtype_init);
352
353         for (l = struct_->members; l; l = l->next)
354           g_ir_node_free ((GIrNode *)l->data);
355         g_list_free (struct_->members);
356       }
357       break;
358
359     case G_IR_NODE_CONSTANT:
360       {
361         GIrNodeConstant *constant = (GIrNodeConstant *)node;
362         
363         g_free (node->name);
364         g_free (constant->value);
365         g_ir_node_free ((GIrNode *)constant->type);
366       }
367       break;
368
369     case G_IR_NODE_ERROR_DOMAIN:
370       {
371         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
372         
373         g_free (node->name);
374         g_free (domain->getquark);
375         g_free (domain->codes);
376       }
377       break;
378
379     case G_IR_NODE_XREF:
380       {
381         GIrNodeXRef *xref = (GIrNodeXRef *)node;
382         
383         g_free (node->name);
384         g_free (xref->namespace);
385       }
386       break;
387
388     case G_IR_NODE_UNION:
389       {
390         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
391         
392         g_free (node->name);
393         g_free (union_->gtype_name);
394         g_free (union_->gtype_init);
395
396         g_ir_node_free ((GIrNode *)union_->discriminator_type);
397         for (l = union_->members; l; l = l->next)
398           g_ir_node_free ((GIrNode *)l->data);
399         for (l = union_->discriminators; l; l = l->next)
400           g_ir_node_free ((GIrNode *)l->data);
401       }
402       break;
403
404     default:
405       g_error ("Unhandled node type %d\n", node->type);
406       break;
407     } 
408
409   g_hash_table_destroy (node->attributes);
410
411   g_free (node);
412 }
413
414 /* returns the fixed size of the blob */
415 guint32
416 g_ir_node_get_size (GIrNode *node)
417 {
418   GList *l;
419   gint size, n;
420
421   switch (node->type)
422     {
423     case G_IR_NODE_CALLBACK:
424       size = sizeof (CallbackBlob);
425       break;
426
427     case G_IR_NODE_FUNCTION:
428       size = sizeof (FunctionBlob);
429       break;
430
431     case G_IR_NODE_PARAM:
432       /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
433       size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
434       break;
435
436     case G_IR_NODE_TYPE:
437       size = sizeof (SimpleTypeBlob);
438       break;
439
440     case G_IR_NODE_OBJECT:
441       {
442         GIrNodeInterface *iface = (GIrNodeInterface *)node;
443
444         n = g_list_length (iface->interfaces);
445         size = sizeof (ObjectBlob) + 2 * (n + (n % 2));
446
447         for (l = iface->members; l; l = l->next)
448           size += g_ir_node_get_size ((GIrNode *)l->data);
449       }
450       break;
451
452     case G_IR_NODE_INTERFACE:
453       {
454         GIrNodeInterface *iface = (GIrNodeInterface *)node;
455
456         n = g_list_length (iface->prerequisites);
457         size = sizeof (InterfaceBlob) + 2 * (n + (n % 2));
458
459         for (l = iface->members; l; l = l->next)
460           size += g_ir_node_get_size ((GIrNode *)l->data);
461       }
462       break;
463
464     case G_IR_NODE_ENUM:
465     case G_IR_NODE_FLAGS:
466       {
467         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
468         
469         size = sizeof (EnumBlob);
470         for (l = enum_->values; l; l = l->next)
471           size += g_ir_node_get_size ((GIrNode *)l->data);
472       }
473       break;
474
475     case G_IR_NODE_VALUE:
476       size = sizeof (ValueBlob);
477       break;
478
479     case G_IR_NODE_STRUCT:
480       {
481         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
482
483         size = sizeof (StructBlob);
484         for (l = struct_->members; l; l = l->next)
485           size += g_ir_node_get_size ((GIrNode *)l->data);
486       }
487       break;
488
489     case G_IR_NODE_BOXED:
490       {
491         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
492
493         size = sizeof (StructBlob);
494         for (l = boxed->members; l; l = l->next)
495           size += g_ir_node_get_size ((GIrNode *)l->data);
496       }
497       break;
498
499     case G_IR_NODE_PROPERTY:
500       size = sizeof (PropertyBlob);
501       break;
502
503     case G_IR_NODE_SIGNAL:
504       size = sizeof (SignalBlob);
505       break;
506
507     case G_IR_NODE_VFUNC:
508       size = sizeof (VFuncBlob);
509       break;
510
511     case G_IR_NODE_FIELD:
512       {
513         GIrNodeField *field = (GIrNodeField *)node;
514
515         size = sizeof (FieldBlob);
516         if (field->callback)
517           size += g_ir_node_get_size ((GIrNode *)field->callback);
518       }
519       break;
520
521     case G_IR_NODE_CONSTANT:
522       size = sizeof (ConstantBlob);
523       break;
524
525     case G_IR_NODE_ERROR_DOMAIN:
526       size = sizeof (ErrorDomainBlob);
527       break;
528
529     case G_IR_NODE_XREF:
530       size = 0;
531       break;
532
533     case G_IR_NODE_UNION:
534       {
535         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
536
537         size = sizeof (UnionBlob);
538         for (l = union_->members; l; l = l->next)
539           size += g_ir_node_get_size ((GIrNode *)l->data);
540         for (l = union_->discriminators; l; l = l->next)
541           size += g_ir_node_get_size ((GIrNode *)l->data);
542       }
543       break;
544
545     default: 
546       g_error ("Unhandled node type '%s'\n",
547                g_ir_node_type_to_string (node->type));
548       size = 0;
549     }
550
551   g_debug ("node %p type '%s' size %d", node,
552            g_ir_node_type_to_string (node->type), size);
553
554   return size;
555 }
556
557 static void
558 add_attribute_size (gpointer key, gpointer value, gpointer data)
559 {
560   const gchar *key_str = key;
561   const gchar *value_str = value;
562   gint *size_p = data;
563
564   *size_p += sizeof (AttributeBlob);
565   *size_p += ALIGN_VALUE (strlen (key_str) + 1, 4);
566   *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4);
567 }
568
569 /* returns the full size of the blob including variable-size parts */
570 static guint32
571 g_ir_node_get_full_size_internal (GIrNode *parent,
572                                   GIrNode *node)
573 {
574   GList *l;
575   gint size, n;
576
577   if (node == NULL && parent != NULL)
578     g_error ("Caught NULL node, parent=%s", parent->name);
579
580   g_debug ("node %p type '%s'", node,
581            g_ir_node_type_to_string (node->type));
582
583   switch (node->type)
584     {
585     case G_IR_NODE_CALLBACK:
586       {
587         GIrNodeFunction *function = (GIrNodeFunction *)node;
588         size = sizeof (CallbackBlob);
589         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
590         for (l = function->parameters; l; l = l->next)
591           {
592             size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
593           }
594         size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
595       }
596       break;
597
598     case G_IR_NODE_FUNCTION:
599       {
600         GIrNodeFunction *function = (GIrNodeFunction *)node;
601         size = sizeof (FunctionBlob);
602         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
603         size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
604         for (l = function->parameters; l; l = l->next)
605           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
606         size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
607       }
608       break;
609
610     case G_IR_NODE_PARAM:
611       {
612         GIrNodeParam *param = (GIrNodeParam *)node;
613         
614         /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
615         size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
616         if (node->name)
617           size += ALIGN_VALUE (strlen (node->name) + 1, 4);
618         size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type);        
619       }
620       break;
621
622     case G_IR_NODE_TYPE:
623       {
624         GIrNodeType *type = (GIrNodeType *)node;
625         size = sizeof (SimpleTypeBlob);
626         if (type->tag >= GI_TYPE_TAG_ARRAY)
627           {
628             g_debug ("node %p type tag '%s'", node,
629                      g_type_tag_to_string (type->tag));
630
631             switch (type->tag)
632               {
633               case GI_TYPE_TAG_ARRAY:
634                 size = sizeof (ArrayTypeBlob);
635                 if (type->parameter_type1)
636                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
637                 break;
638               case GI_TYPE_TAG_INTERFACE:
639                 size += sizeof (InterfaceTypeBlob);
640                 break;
641               case GI_TYPE_TAG_GLIST:
642               case GI_TYPE_TAG_GSLIST:
643                 size += sizeof (ParamTypeBlob);
644                 if (type->parameter_type1)
645                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
646                 break;
647               case GI_TYPE_TAG_GHASH:
648                 size += sizeof (ParamTypeBlob) * 2;
649                 if (type->parameter_type1)
650                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
651                 if (type->parameter_type2)
652                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2);
653                 break;
654               case GI_TYPE_TAG_ERROR:
655                 {
656                   gint n;
657                   
658                   if (type->errors)
659                     n = g_strv_length (type->errors);
660                   else
661                     n = 0;
662
663                   size += sizeof (ErrorTypeBlob) + 2 * (n + n % 2);
664                 }
665                 break;
666               default:
667                 g_error ("Unknown type tag %d\n", type->tag);
668                 break;
669               }
670           }
671       }
672       break;
673
674     case G_IR_NODE_OBJECT:
675       {
676         GIrNodeInterface *iface = (GIrNodeInterface *)node;
677
678         n = g_list_length (iface->interfaces);
679         size = sizeof(ObjectBlob);
680         if (iface->parent)
681           size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
682         if (iface->glib_type_struct)
683           size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4);
684         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
685         size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
686         if (iface->gtype_init)
687           size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
688         size += 2 * (n + (n % 2));
689
690         for (l = iface->members; l; l = l->next)
691           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
692       }
693       break;
694
695     case G_IR_NODE_INTERFACE:
696       {
697         GIrNodeInterface *iface = (GIrNodeInterface *)node;
698
699         n = g_list_length (iface->prerequisites);
700         size = sizeof (InterfaceBlob);
701         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
702         size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
703         size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
704         size += 2 * (n + (n % 2));
705
706         for (l = iface->members; l; l = l->next)
707           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
708       }
709       break;
710
711     case G_IR_NODE_ENUM:
712     case G_IR_NODE_FLAGS:
713       {
714         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
715         
716         size = sizeof (EnumBlob);
717         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
718         if (enum_->gtype_name)
719           {
720             size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
721             size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
722           }
723
724         for (l = enum_->values; l; l = l->next)
725           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);  
726       }
727       break;
728
729     case G_IR_NODE_VALUE:
730       {
731         size = sizeof (ValueBlob);
732         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
733       }
734       break;
735
736     case G_IR_NODE_STRUCT:
737       {
738         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
739
740         size = sizeof (StructBlob);
741         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
742         if (struct_->gtype_name)
743           size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
744         if (struct_->gtype_init)
745           size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
746         for (l = struct_->members; l; l = l->next)
747           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
748       }
749       break;
750
751     case G_IR_NODE_BOXED:
752       {
753         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
754
755         size = sizeof (StructBlob);
756         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
757         if (boxed->gtype_name)
758           {
759             size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
760             size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
761           }
762         for (l = boxed->members; l; l = l->next)
763           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
764       }
765       break;
766
767     case G_IR_NODE_PROPERTY:
768       {
769         GIrNodeProperty *prop = (GIrNodeProperty *)node;
770         
771         size = sizeof (PropertyBlob);
772         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
773         size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); 
774       }
775       break;
776
777     case G_IR_NODE_SIGNAL:
778       {
779         GIrNodeSignal *signal = (GIrNodeSignal *)node;
780
781         size = sizeof (SignalBlob);
782         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
783         for (l = signal->parameters; l; l = l->next)
784           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
785         size += g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result);
786       }
787       break;
788
789     case G_IR_NODE_VFUNC:
790       {
791         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
792
793         size = sizeof (VFuncBlob);
794         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
795         for (l = vfunc->parameters; l; l = l->next)
796           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
797         size += g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result);
798       }
799       break;
800
801     case G_IR_NODE_FIELD:
802       {
803         GIrNodeField *field = (GIrNodeField *)node;
804
805         size = sizeof (FieldBlob);
806         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
807         if (field->callback)
808           size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->callback);
809         else
810           size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);
811       }
812       break;
813
814     case G_IR_NODE_CONSTANT:
815       {
816         GIrNodeConstant *constant = (GIrNodeConstant *)node;
817
818         size = sizeof (ConstantBlob);
819         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
820         /* FIXME non-string values */
821         size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
822         size += g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type);     
823       }
824       break;
825
826     case G_IR_NODE_ERROR_DOMAIN:
827       {
828         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
829
830         size = sizeof (ErrorDomainBlob);
831         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
832         size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
833       }
834       break;
835
836     case G_IR_NODE_XREF:
837       {
838         GIrNodeXRef *xref = (GIrNodeXRef *)node;
839         
840         size = 0;
841         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
842         size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
843       }
844       break;
845
846     case G_IR_NODE_UNION:
847       {
848         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
849
850         size = sizeof (UnionBlob);
851         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
852         if (union_->gtype_name)
853           size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
854         if (union_->gtype_init)
855           size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
856         for (l = union_->members; l; l = l->next)
857           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
858         for (l = union_->discriminators; l; l = l->next)
859           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
860       }
861       break;
862
863     default: 
864       g_error ("Unknown type tag %d\n", node->type);
865       size = 0;
866     }
867
868   g_debug ("node %s%s%s%p type '%s' full size %d",
869            node->name ? "'" : "",
870            node->name ? node->name : "",
871            node->name ? "' " : "",
872            node, g_ir_node_type_to_string (node->type), size);
873
874   return size;
875 }
876
877 guint32
878 g_ir_node_get_full_size (GIrNode *node)
879 {
880   return g_ir_node_get_full_size_internal (NULL, node);
881 }
882
883 guint32
884 g_ir_node_get_attribute_size (GIrNode *node)
885 {
886   guint32 size = 0;
887   g_hash_table_foreach (node->attributes, add_attribute_size, &size);
888   return size;
889 }
890
891 int
892 g_ir_node_cmp (GIrNode *node,
893                 GIrNode *other)
894 {
895   if (node->type < other->type)
896     return -1;
897   else if (node->type > other->type)
898     return 1;
899   else
900     return strcmp (node->name, other->name);
901 }
902
903 gboolean
904 g_ir_node_can_have_member (GIrNode    *node)
905 {
906   switch (node->type)
907     {
908     case G_IR_NODE_OBJECT:
909     case G_IR_NODE_INTERFACE:
910     case G_IR_NODE_BOXED:
911     case G_IR_NODE_STRUCT:
912     case G_IR_NODE_UNION:
913       return TRUE;
914     /* list others individually rather than with default: so that compiler
915      * warns if new node types are added without adding them to the switch
916      */
917     case G_IR_NODE_INVALID:
918     case G_IR_NODE_FUNCTION:
919     case G_IR_NODE_CALLBACK:
920     case G_IR_NODE_ENUM:
921     case G_IR_NODE_FLAGS:
922     case G_IR_NODE_CONSTANT:
923     case G_IR_NODE_ERROR_DOMAIN:
924     case G_IR_NODE_PARAM:
925     case G_IR_NODE_TYPE:
926     case G_IR_NODE_PROPERTY:
927     case G_IR_NODE_SIGNAL:
928     case G_IR_NODE_VALUE:
929     case G_IR_NODE_VFUNC:
930     case G_IR_NODE_FIELD:
931     case G_IR_NODE_XREF:
932       return FALSE;
933     };
934   return FALSE;
935 }
936
937 void
938 g_ir_node_add_member (GIrNode         *node,
939                       GIrNodeFunction *member)
940 {
941   g_return_if_fail (node != NULL);
942   g_return_if_fail (member != NULL);
943                     
944   switch (node->type)
945     {
946     case G_IR_NODE_OBJECT:
947     case G_IR_NODE_INTERFACE:
948       {
949         GIrNodeInterface *iface = (GIrNodeInterface *)node;
950         iface->members =
951           g_list_insert_sorted (iface->members, member,
952                                 (GCompareFunc) g_ir_node_cmp);
953         break;
954       }
955     case G_IR_NODE_BOXED:
956       {
957         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
958         boxed->members =
959           g_list_insert_sorted (boxed->members, member,
960                                 (GCompareFunc) g_ir_node_cmp);
961         break;
962       }
963     case G_IR_NODE_STRUCT:
964       {
965         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
966         struct_->members =
967           g_list_insert_sorted (struct_->members, member,
968                                 (GCompareFunc) g_ir_node_cmp);
969         break;
970       }
971     case G_IR_NODE_UNION:
972       {
973         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
974         union_->members =
975           g_list_insert_sorted (union_->members, member,
976                                 (GCompareFunc) g_ir_node_cmp);
977         break;
978       }
979     default:
980       g_error ("Cannot add a member to unknown type tag type %d\n",
981                node->type);
982       break;
983     }
984 }
985
986 const gchar *
987 g_ir_node_param_direction_string (GIrNodeParam * node)
988 {
989   if (node->out)
990     {
991       if (node->in)
992         return "in-out";
993       else
994         return "out";
995     }
996   return "in";
997 }
998
999 static gint64
1000 parse_int_value (const gchar *str)
1001 {
1002   return strtoll (str, NULL, 0);
1003 }
1004
1005 static guint64
1006 parse_uint_value (const gchar *str)
1007 {
1008   return strtoull (str, NULL, 0);
1009 }
1010
1011 static gdouble
1012 parse_float_value (const gchar *str)
1013 {
1014   return strtod (str, NULL);
1015 }
1016
1017 static gboolean
1018 parse_boolean_value (const gchar *str)
1019 {
1020   if (strcmp (str, "TRUE") == 0)
1021     return TRUE;
1022   
1023   if (strcmp (str, "FALSE") == 0)
1024     return FALSE;
1025
1026   return parse_int_value (str) ? TRUE : FALSE;
1027 }
1028
1029 static GIrNode *
1030 find_entry_node (GIrModule   *module,
1031                  GList       *modules,
1032                  const gchar *name,
1033                  guint16     *idx)
1034
1035 {
1036   GList *l;
1037   gint i;
1038   gchar **names;
1039   gint n_names;
1040   GIrNode *result = NULL;
1041
1042   g_assert (name != NULL);
1043   g_assert (strlen (name) > 0);
1044   
1045   names = g_strsplit (name, ".", 0);
1046   n_names = g_strv_length (names);
1047   if (n_names > 2)
1048     g_error ("Too many name parts");
1049   
1050   for (l = module->entries, i = 1; l; l = l->next, i++)
1051     {
1052       GIrNode *node = (GIrNode *)l->data;
1053       
1054       if (n_names > 1)
1055         {
1056           if (node->type != G_IR_NODE_XREF)
1057             continue;
1058           
1059           if (((GIrNodeXRef *)node)->namespace == NULL ||
1060               strcmp (((GIrNodeXRef *)node)->namespace, names[0]) != 0)
1061             continue;
1062         }
1063          
1064       if (strcmp (node->name, names[n_names - 1]) == 0)
1065         {
1066           if (idx)
1067             *idx = i;
1068           
1069           result = node;
1070           goto out;
1071         }
1072     }
1073
1074   if (n_names > 1)
1075     {
1076       GIrNode *node = g_ir_node_new (G_IR_NODE_XREF);
1077
1078       ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]);
1079       node->name = g_strdup (names[1]);
1080   
1081       module->entries = g_list_append (module->entries, node);
1082   
1083       if (idx)
1084         *idx = g_list_length (module->entries);
1085
1086       result = node;
1087
1088       g_debug ("Creating XREF: %s %s", names[0], names[1]);
1089
1090       goto out;
1091     }
1092
1093   g_ir_module_fatal (module, 0, "Type reference '%s' not found", name);
1094
1095  out:
1096
1097   g_strfreev (names);
1098
1099   return result;
1100 }
1101
1102 static guint16
1103 find_entry (GIrModule   *module,
1104             GList       *modules,
1105             const gchar *name)
1106 {
1107   guint16 idx = 0;
1108
1109   find_entry_node (module, modules, name, &idx);
1110
1111   return idx;
1112 }
1113
1114 static GIrNode *
1115 find_name_in_module (GIrModule   *module,
1116                      const gchar *name)
1117 {
1118   GList *l;
1119
1120   for (l = module->entries; l; l = l->next)
1121     {
1122       GIrNode *node = (GIrNode *)l->data;
1123
1124       if (strcmp (node->name, name) == 0)
1125         return node;
1126     }
1127
1128   return NULL;
1129 }
1130
1131 gboolean
1132 g_ir_find_node (GIrModule  *module,
1133                 GList      *modules,
1134                 const char *name,
1135                 GIrNode   **node_out,
1136                 GIrModule **module_out)
1137 {
1138   char **names = g_strsplit (name, ".", 0);
1139   gint n_names = g_strv_length (names);
1140   GIrNode *node = NULL;
1141   GList *l;
1142
1143   if (n_names == 0)
1144     {
1145       g_warning ("Name can't be empty");
1146       goto out;
1147     }
1148
1149   if (n_names > 2)
1150     {
1151       g_warning ("Too many name parts in '%s'", name);
1152       goto out;
1153     }
1154
1155   if (n_names == 1)
1156     {
1157       *module_out = module;
1158       node = find_name_in_module (module, names[0]);
1159     }
1160   else if (strcmp (names[0], module->name) == 0)
1161     {
1162       *module_out = module;
1163       node = find_name_in_module (module, names[1]);
1164     }
1165   else
1166     {
1167       for (l = module->include_modules; l; l = l->next)
1168         {
1169           GIrModule *m = l->data;
1170
1171           if (strcmp (names[0], m->name) == 0)
1172             {
1173               *module_out = m;
1174               node = find_name_in_module (m, names[1]);
1175               goto out;
1176             }
1177         }
1178
1179       for (l = modules; l; l = l->next)
1180         {
1181           GIrModule *m = l->data;
1182
1183           if (strcmp (names[0], m->name) == 0)
1184             {
1185               *module_out = m;
1186               node = find_name_in_module (m, names[1]);
1187               goto out;
1188             }
1189         }
1190     }
1191
1192  out:
1193   g_strfreev (names);
1194
1195   *node_out = node;
1196
1197   return node != NULL;
1198 }
1199
1200 static int
1201 get_index_of_member_type (GIrNodeInterface *node,
1202                           GIrNodeTypeId type,
1203                           const char *name)
1204 {
1205   guint index = -1;
1206   GList *l;
1207
1208   for (l = node->members; l; l = l->next)
1209     {
1210       GIrNode *node = l->data;
1211
1212       if (node->type != type)
1213         continue;
1214
1215       index++;
1216
1217       if (strcmp (node->name, name) == 0)
1218         break;
1219     }
1220
1221   return index;
1222 }
1223
1224 static void
1225 serialize_type (GIrModule    *module, 
1226                 GList        *modules,
1227                 GIrNodeType  *node, 
1228                 GString      *str)
1229 {
1230   gint i;
1231   const gchar* basic[] = {
1232     "void", 
1233     "boolean", 
1234     "int8", 
1235     "uint8", 
1236     "int16", 
1237     "uint16", 
1238     "int32", 
1239     "uint32", 
1240     "int64", 
1241     "uint64", 
1242     "short",
1243     "ushort",
1244     "int",
1245     "uint",
1246     "long",
1247     "ulong",
1248     "ssize",
1249     "size",
1250     "float", 
1251     "double",
1252     "time_t",
1253     "GType",
1254     "utf8", 
1255     "filename",
1256   };
1257   
1258   if (node->tag < GI_TYPE_TAG_ARRAY)
1259     {
1260       g_string_append_printf (str, "%s%s", basic[node->tag],
1261                               node->is_pointer ? "*" : "");
1262     }
1263   else if (node->tag == GI_TYPE_TAG_ARRAY)
1264     {
1265       serialize_type (module, modules, node->parameter_type1, str);
1266       g_string_append (str, "[");
1267
1268       if (node->has_length)
1269         g_string_append_printf (str, "length=%d", node->length);
1270       else if (node->has_size)
1271         g_string_append_printf (str, "fixed-size=%d", node->size);
1272       
1273       if (node->zero_terminated)
1274         g_string_append_printf (str, "%szero-terminated=1", 
1275                                 node->has_length ? "," : "");
1276       
1277       g_string_append (str, "]");
1278     }
1279   else if (node->tag == GI_TYPE_TAG_INTERFACE)
1280     {
1281       GIrNode *iface;
1282       gchar *name;
1283
1284       iface = find_entry_node (module, modules, node->interface, NULL);
1285       if (iface)
1286         {
1287           if (iface->type == G_IR_NODE_XREF)
1288             g_string_append_printf (str, "%s.", ((GIrNodeXRef *)iface)->namespace);
1289           name = iface->name;
1290         }
1291       else
1292         {
1293           g_warning ("Interface for type reference %s not found", node->interface);
1294           name = node->interface;
1295         }
1296
1297       g_string_append_printf (str, "%s%s", name,
1298                               node->is_pointer ? "*" : "");
1299     }
1300   else if (node->tag == GI_TYPE_TAG_GLIST)
1301     {
1302       g_string_append (str, "GList");
1303       if (node->parameter_type1)
1304         {
1305           g_string_append (str, "<"); 
1306           serialize_type (module, modules, node->parameter_type1, str);
1307           g_string_append (str, ">"); 
1308         }
1309     }
1310   else if (node->tag == GI_TYPE_TAG_GSLIST)
1311     {
1312       g_string_append (str, "GSList");
1313       if (node->parameter_type1)
1314         {
1315           g_string_append (str, "<"); 
1316           serialize_type (module, modules, node->parameter_type1, str);
1317           g_string_append (str, ">"); 
1318         }
1319     }
1320   else if (node->tag == GI_TYPE_TAG_GHASH)
1321     {
1322       g_string_append (str, "GHashTable<");
1323       if (node->parameter_type1)
1324         {
1325           g_string_append (str, "<"); 
1326           serialize_type (module, modules, node->parameter_type1, str);
1327           g_string_append (str, ","); 
1328           serialize_type (module, modules, node->parameter_type2, str);
1329           g_string_append (str, ">"); 
1330         }
1331     }
1332   else if (node->tag == GI_TYPE_TAG_ERROR)
1333     {
1334       g_string_append (str, "GError");
1335       if (node->errors)
1336         {
1337           g_string_append (str, "<"); 
1338           for (i = 0; node->errors[i]; i++)
1339             {
1340               if (i > 0)
1341                 g_string_append (str, ",");
1342               g_string_append (str, node->errors[i]);
1343             }
1344           g_string_append (str, ">"); 
1345         }
1346     }
1347 }
1348
1349 static void
1350 g_ir_node_build_members (GList         **members,
1351                          GIrNodeTypeId   type,
1352                          guint16        *count,
1353                          GIrNode        *parent,
1354                          GIrTypelibBuild *build,
1355                          guint32        *offset,
1356                          guint32        *offset2)
1357 {
1358   GList *l = *members;
1359
1360   while (l)
1361     {
1362       GIrNode *member = (GIrNode *)l->data;
1363       GList *next = l->next;
1364
1365       if (member->type == type)
1366         {
1367           (*count)++;
1368           g_ir_node_build_typelib (member, parent, build, offset, offset2);
1369           *members = g_list_delete_link (*members, l);
1370         }
1371       l = next;
1372     }
1373 }
1374
1375 static void
1376 g_ir_node_check_unhandled_members (GList         **members,
1377                                    GIrNodeTypeId   container_type)
1378 {
1379 #if 0
1380   if (*members)
1381     {
1382       GList *l;
1383
1384       for (l = *members; l; l = l->next)
1385         {
1386           GIrNode *member = (GIrNode *)l->data;
1387           g_printerr ("Unhandled '%s' member '%s' type '%s'\n",
1388                       g_ir_node_type_to_string (container_type),
1389                       member->name,
1390                       g_ir_node_type_to_string (member->type));
1391         }
1392
1393       g_list_free (*members);
1394       *members = NULL;
1395
1396       g_error ("Unhandled members. Aborting.");
1397     }
1398 #else
1399   g_list_free (*members);
1400   *members = NULL;
1401 #endif
1402 }
1403
1404 void
1405 g_ir_node_build_typelib (GIrNode         *node,
1406                          GIrNode         *parent,
1407                          GIrTypelibBuild *build,
1408                          guint32         *offset,
1409                          guint32         *offset2)
1410 {
1411   GIrModule *module = build->module;
1412   GList *modules = build->modules;
1413   GHashTable *strings = build->strings;
1414   GHashTable *types = build->types;
1415   guchar *data = build->data;
1416   GList *l;
1417   guint32 old_offset = *offset;
1418   guint32 old_offset2 = *offset2;
1419
1420   g_assert (node != NULL);
1421
1422   g_debug ("build_typelib: %s%s(%s)",
1423            node->name ? node->name : "",
1424            node->name ? " " : "",
1425            g_ir_node_type_to_string (node->type));
1426
1427   g_ir_node_compute_offsets (node, module, modules);
1428
1429   /* We should only be building each node once.  If we do a typelib expansion, we also
1430    * reset the offset in girmodule.c.
1431    */
1432   g_assert (node->offset == 0);
1433   node->offset = *offset;
1434   build->offset_ordered_nodes = g_list_prepend (build->offset_ordered_nodes, node);
1435
1436   build->n_attributes += g_hash_table_size (node->attributes);
1437
1438   switch (node->type)
1439     {
1440     case G_IR_NODE_TYPE:
1441       {
1442         GIrNodeType *type = (GIrNodeType *)node;
1443         SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1444
1445         *offset += sizeof (SimpleTypeBlob);
1446         
1447         if (type->tag < GI_TYPE_TAG_ARRAY ||
1448             type->tag == GI_TYPE_TAG_UTF8 ||
1449             type->tag == GI_TYPE_TAG_FILENAME)
1450           { 
1451             blob->flags.reserved = 0;
1452             blob->flags.reserved2 = 0;
1453             blob->flags.pointer = type->is_pointer;
1454             blob->flags.reserved3 = 0;
1455             blob->flags.tag = type->tag;
1456           }
1457         else 
1458           {
1459             GString *str;
1460             gchar *s;
1461             gpointer value;
1462             
1463             str = g_string_new (0);
1464             serialize_type (module, modules, type, str);
1465             s = g_string_free (str, FALSE);
1466             
1467             types_count += 1;
1468             value = g_hash_table_lookup (types, s);
1469             if (value)
1470               {
1471                 blob->offset = GPOINTER_TO_UINT (value);
1472                 g_free (s);
1473               }
1474             else
1475               {
1476                 unique_types_count += 1;
1477                 g_hash_table_insert (types, s, GUINT_TO_POINTER(*offset2));
1478                                      
1479                 blob->offset = *offset2;
1480                 switch (type->tag)
1481                   {
1482                   case GI_TYPE_TAG_ARRAY:
1483                     {
1484                       ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1485                       guint32 pos;
1486                       
1487                       array->pointer = 1;
1488                       array->reserved = 0;
1489                       array->tag = type->tag;
1490                       array->zero_terminated = type->zero_terminated;
1491                       array->has_length = type->has_length;
1492                       array->has_size = type->has_size;
1493                       array->reserved2 = 0;
1494                       if (array->has_length)
1495                         array->dimensions.length = type->length;
1496                       else if (array->has_size)
1497                         array->dimensions.size  = type->size;
1498                       else
1499                         array->dimensions.length = -1;
1500                       
1501                       pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type);
1502                       *offset2 += sizeof (ArrayTypeBlob);
1503                       
1504                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1,
1505                                                node, build, &pos, offset2);
1506                     }
1507                     break;
1508                     
1509                   case GI_TYPE_TAG_INTERFACE:
1510                     {
1511                       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1512                       *offset2 += sizeof (InterfaceTypeBlob);
1513
1514                       iface->pointer = type->is_pointer;
1515                       iface->reserved = 0;
1516                       iface->tag = type->tag;
1517                       iface->reserved2 = 0;
1518                       iface->interface = find_entry (module, modules, type->interface);
1519
1520                     }
1521                     break;
1522                     
1523                   case GI_TYPE_TAG_GLIST:
1524                   case GI_TYPE_TAG_GSLIST:
1525                     {
1526                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1527                       guint32 pos;
1528                       
1529                       param->pointer = 1;
1530                       param->reserved = 0;
1531                       param->tag = type->tag;
1532                       param->reserved2 = 0;
1533                       param->n_types = 1;
1534                       
1535                       pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1536                       *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob);
1537                       
1538                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
1539                                                node, build, &pos, offset2);
1540                     }
1541                     break;
1542                     
1543                   case GI_TYPE_TAG_GHASH:
1544                     {
1545                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1546                       guint32 pos;
1547                       
1548                       param->pointer = 1;
1549                       param->reserved = 0;
1550                       param->tag = type->tag;
1551                       param->reserved2 = 0;
1552                       param->n_types = 2;
1553                       
1554                       pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1555                       *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2;
1556                       
1557                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
1558                                                node, build, &pos, offset2);
1559                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, 
1560                                                node, build, &pos, offset2);
1561                     }
1562                     break;
1563                     
1564                   case GI_TYPE_TAG_ERROR:
1565                     {
1566                       ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1567                       gint i;
1568                       
1569                       blob->pointer = 1;
1570                       blob->reserved = 0;
1571                       blob->tag = type->tag;
1572                       blob->reserved2 = 0;
1573                       if (type->errors) 
1574                         blob->n_domains = g_strv_length (type->errors);
1575                       else
1576                         blob->n_domains = 0;
1577                       
1578                       *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains)
1579                                               + 2 * blob->n_domains, 4);
1580                       for (i = 0; i < blob->n_domains; i++)
1581                         blob->domains[i] = find_entry (module, modules, type->errors[i]);
1582                     }
1583                     break;
1584                     
1585                   default:
1586                     g_error ("Unknown type tag %d\n", type->tag);
1587                     break;
1588                   }
1589               }
1590           }
1591       }
1592       break;
1593
1594     case G_IR_NODE_FIELD:
1595       {
1596         GIrNodeField *field = (GIrNodeField *)node;
1597         FieldBlob *blob;
1598
1599         blob = (FieldBlob *)&data[*offset];
1600
1601         blob->name = write_string (node->name, strings, data, offset2);
1602         blob->readable = field->readable;
1603         blob->writable = field->writable;
1604         blob->reserved = 0;
1605         blob->bits = 0;
1606         if (field->offset >= 0)
1607           blob->struct_offset = field->offset;
1608         else
1609           blob->struct_offset = 0xFFFF; /* mark as unknown */
1610
1611         if (field->callback)
1612           {
1613             blob->has_embedded_type = TRUE;
1614             blob->type.offset = GI_INFO_TYPE_CALLBACK;
1615             *offset += sizeof (FieldBlob);
1616             g_ir_node_build_typelib ((GIrNode *)field->callback,
1617                                      node, build, offset, offset2);
1618           }
1619         else
1620           {
1621             blob->has_embedded_type = FALSE;
1622             /* We handle the size member specially below, so subtract it */
1623             *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
1624             g_ir_node_build_typelib ((GIrNode *)field->type,
1625                                      node, build, offset, offset2);
1626           }
1627       }
1628       break;
1629
1630     case G_IR_NODE_PROPERTY:
1631       {
1632         GIrNodeProperty *prop = (GIrNodeProperty *)node;
1633         PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1634         /* We handle the size member specially below, so subtract it */
1635         *offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob);
1636
1637         blob->name = write_string (node->name, strings, data, offset2);
1638         blob->deprecated = prop->deprecated;
1639         blob->readable = prop->readable;
1640         blob->writable = prop->writable;
1641         blob->construct = prop->construct;
1642         blob->construct_only = prop->construct_only;
1643         blob->reserved = 0;
1644
1645         g_ir_node_build_typelib ((GIrNode *)prop->type, 
1646                                  node, build, offset, offset2);
1647       }
1648       break;
1649
1650     case G_IR_NODE_FUNCTION:
1651       {
1652         FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1653         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1654         GIrNodeFunction *function = (GIrNodeFunction *)node;
1655         guint32 signature;
1656         gint n;
1657
1658         signature = *offset2;
1659         n = g_list_length (function->parameters);
1660
1661         *offset += sizeof (FunctionBlob);
1662         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1663
1664         blob->blob_type = BLOB_TYPE_FUNCTION;
1665         blob->deprecated = function->deprecated;
1666         blob->is_static = !function->is_method;
1667         blob->setter = function->is_setter;
1668         blob->getter = function->is_getter;
1669         blob->constructor = function->is_constructor;
1670         blob->wraps_vfunc = function->wraps_vfunc;
1671         blob->throws = function->throws;
1672         blob->index = 0;
1673         blob->name = write_string (node->name, strings, data, offset2);
1674         blob->symbol = write_string (function->symbol, strings, data, offset2);
1675         blob->signature = signature;
1676
1677         g_debug ("building function '%s'", function->symbol);
1678
1679         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
1680                                  node, build, &signature, offset2);
1681
1682         blob2->may_return_null = function->result->allow_none;
1683         blob2->caller_owns_return_value = function->result->transfer;
1684         blob2->caller_owns_return_container = function->result->shallow_transfer;
1685         blob2->reserved = 0;
1686         blob2->n_arguments = n;
1687
1688         signature += 4;
1689         
1690         for (l = function->parameters; l; l = l->next)
1691           {
1692             GIrNode *param = (GIrNode *)l->data;
1693
1694             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1695           }
1696
1697       }
1698       break;
1699
1700     case G_IR_NODE_CALLBACK:
1701       {
1702         CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1703         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1704         GIrNodeFunction *function = (GIrNodeFunction *)node;
1705         guint32 signature;
1706         gint n;
1707
1708         signature = *offset2;
1709         n = g_list_length (function->parameters);
1710
1711         *offset += sizeof (CallbackBlob);
1712         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1713
1714         blob->blob_type = BLOB_TYPE_CALLBACK;
1715         blob->deprecated = function->deprecated;
1716         blob->reserved = 0;
1717         blob->name = write_string (node->name, strings, data, offset2);
1718         blob->signature = signature;
1719         
1720         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
1721                                  node, build, &signature, offset2);
1722
1723         blob2->may_return_null = function->result->allow_none;
1724         blob2->caller_owns_return_value = function->result->transfer;
1725         blob2->caller_owns_return_container = function->result->shallow_transfer;
1726         blob2->reserved = 0;
1727         blob2->n_arguments = n;
1728
1729         signature += 4;
1730         
1731         for (l = function->parameters; l; l = l->next)
1732           {
1733             GIrNode *param = (GIrNode *)l->data;
1734
1735             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1736           }
1737       }
1738       break;
1739
1740     case G_IR_NODE_SIGNAL:
1741       {
1742         SignalBlob *blob = (SignalBlob *)&data[*offset];
1743         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1744         GIrNodeSignal *signal = (GIrNodeSignal *)node;
1745         guint32 signature;
1746         gint n;
1747
1748         signature = *offset2;
1749         n = g_list_length (signal->parameters);
1750
1751         *offset += sizeof (SignalBlob);
1752         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1753
1754         blob->deprecated = signal->deprecated;
1755         blob->run_first = signal->run_first;
1756         blob->run_last = signal->run_last;
1757         blob->run_cleanup = signal->run_cleanup;
1758         blob->no_recurse = signal->no_recurse;
1759         blob->detailed = signal->detailed;
1760         blob->action = signal->action;
1761         blob->no_hooks = signal->no_hooks;
1762         blob->has_class_closure = 0; /* FIXME */
1763         blob->true_stops_emit = 0; /* FIXME */
1764         blob->reserved = 0;
1765         blob->class_closure = 0; /* FIXME */
1766         blob->name = write_string (node->name, strings, data, offset2);
1767         blob->signature = signature;
1768         
1769         g_ir_node_build_typelib ((GIrNode *)signal->result->type, 
1770                                  node, build, &signature, offset2);
1771
1772         blob2->may_return_null = signal->result->allow_none;
1773         blob2->caller_owns_return_value = signal->result->transfer;
1774         blob2->caller_owns_return_container = signal->result->shallow_transfer;
1775         blob2->reserved = 0;
1776         blob2->n_arguments = n;
1777
1778         signature += 4;
1779         
1780         for (l = signal->parameters; l; l = l->next)
1781           {
1782             GIrNode *param = (GIrNode *)l->data;
1783
1784             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1785           }
1786       }
1787       break;
1788
1789     case G_IR_NODE_VFUNC:
1790       {
1791         VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1792         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1793         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
1794         guint32 signature;
1795         gint n;
1796
1797         signature = *offset2;
1798         n = g_list_length (vfunc->parameters);
1799
1800         *offset += sizeof (VFuncBlob);
1801         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1802
1803         blob->name = write_string (node->name, strings, data, offset2);
1804         blob->must_chain_up = 0; /* FIXME */
1805         blob->must_be_implemented = 0; /* FIXME */
1806         blob->must_not_be_implemented = 0; /* FIXME */
1807         blob->class_closure = 0; /* FIXME */
1808         blob->reserved = 0;
1809
1810         if (vfunc->invoker)
1811           {
1812             int index = get_index_of_member_type ((GIrNodeInterface*)parent, G_IR_NODE_FUNCTION, vfunc->invoker);
1813             if (index == -1)
1814               {
1815                 g_error ("Unknown member function %s for vfunc %s", vfunc->invoker, node->name);
1816               }
1817             blob->invoker = (guint) index;
1818           }
1819         else
1820           blob->invoker = 0x3ff; /* max of 10 bits */
1821
1822         blob->struct_offset = vfunc->offset;
1823         blob->reserved2 = 0;
1824         blob->signature = signature;
1825         
1826         g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, 
1827                                  node, build, &signature, offset2);
1828
1829         blob2->may_return_null = vfunc->result->allow_none;
1830         blob2->caller_owns_return_value = vfunc->result->transfer;
1831         blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1832         blob2->reserved = 0;
1833         blob2->n_arguments = n;
1834
1835         signature += 4;
1836         
1837         for (l = vfunc->parameters; l; l = l->next)
1838           {
1839             GIrNode *param = (GIrNode *)l->data;
1840
1841             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1842           }
1843       }
1844       break;
1845
1846     case G_IR_NODE_PARAM:
1847       {
1848         ArgBlob *blob = (ArgBlob *)&data[*offset];
1849         GIrNodeParam *param = (GIrNodeParam *)node;
1850
1851         /* The offset for this one is smaller than the struct because
1852          * we recursively build the simple type inline here below.
1853          */
1854         *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
1855
1856         blob->name = write_string (node->name, strings, data, offset2);
1857         blob->in = param->in;
1858         blob->out = param->out;
1859         blob->dipper = param->dipper;
1860         blob->allow_none = param->allow_none;
1861         blob->optional = param->optional;
1862         blob->transfer_ownership = param->transfer;
1863         blob->transfer_container_ownership = param->shallow_transfer;
1864         blob->return_value = param->retval;
1865         blob->scope = param->scope;
1866         blob->reserved = 0;
1867         blob->closure = param->closure;
1868         blob->destroy = param->destroy;
1869         
1870         g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2);
1871       }
1872       break;
1873
1874     case G_IR_NODE_STRUCT:
1875       {
1876         StructBlob *blob = (StructBlob *)&data[*offset];
1877         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
1878         GList *members;
1879         
1880         blob->blob_type = BLOB_TYPE_STRUCT;
1881         blob->deprecated = struct_->deprecated;
1882         blob->is_gtype_struct = struct_->is_gtype_struct;
1883         blob->reserved = 0;
1884         blob->name = write_string (node->name, strings, data, offset2);
1885         blob->alignment = struct_->alignment;
1886         blob->size = struct_->size;
1887
1888         if (struct_->gtype_name)
1889           {
1890             blob->unregistered = FALSE;
1891             blob->gtype_name = write_string (struct_->gtype_name, strings, data, offset2);
1892             blob->gtype_init = write_string (struct_->gtype_init, strings, data, offset2);
1893           }
1894         else
1895           {
1896             blob->unregistered = TRUE;
1897             blob->gtype_name = 0;
1898             blob->gtype_init = 0;
1899           }
1900
1901         blob->n_fields = 0;
1902         blob->n_methods = 0;
1903
1904         *offset += sizeof (StructBlob);
1905
1906         members = g_list_copy (struct_->members);
1907
1908         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1909                                  node, build, offset, offset2);
1910
1911         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1912                                  node, build, offset, offset2);
1913
1914         g_ir_node_check_unhandled_members (&members, node->type);
1915
1916         g_assert (members == NULL);
1917       }
1918       break;
1919
1920     case G_IR_NODE_BOXED:
1921       {
1922         StructBlob *blob = (StructBlob *)&data[*offset];
1923         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
1924         GList *members;
1925
1926         blob->blob_type = BLOB_TYPE_BOXED;
1927         blob->deprecated = boxed->deprecated;
1928         blob->unregistered = FALSE;
1929         blob->reserved = 0;
1930         blob->name = write_string (node->name, strings, data, offset2);
1931         blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1932         blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1933         blob->alignment = boxed->alignment;
1934         blob->size = boxed->size;
1935
1936         blob->n_fields = 0;
1937         blob->n_methods = 0;
1938
1939         *offset += sizeof (StructBlob);
1940
1941         members = g_list_copy (boxed->members);
1942
1943         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1944                                  node, build, offset, offset2);
1945
1946         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1947                                  node, build, offset, offset2);
1948
1949         g_ir_node_check_unhandled_members (&members, node->type);
1950
1951         g_assert (members == NULL);
1952       }
1953       break;
1954
1955     case G_IR_NODE_UNION:
1956       {
1957         UnionBlob *blob = (UnionBlob *)&data[*offset];
1958         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
1959         GList *members;
1960
1961         blob->blob_type = BLOB_TYPE_UNION;
1962         blob->deprecated = union_->deprecated;
1963         blob->reserved = 0;
1964         blob->name = write_string (node->name, strings, data, offset2);
1965         blob->alignment = union_->alignment;
1966         blob->size = union_->size;
1967         if (union_->gtype_name)
1968           {
1969             blob->unregistered = FALSE;
1970             blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1971             blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1972           }
1973         else
1974           {
1975             blob->unregistered = TRUE;
1976             blob->gtype_name = 0;
1977             blob->gtype_init = 0;
1978           }
1979
1980         blob->n_fields = 0;
1981         blob->n_functions = 0;
1982
1983         blob->discriminator_offset = union_->discriminator_offset;
1984
1985         /* We don't support Union discriminators right now. */
1986         /*
1987         if (union_->discriminator_type)
1988           {
1989             *offset += 28;
1990             blob->discriminated = TRUE;
1991             g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, 
1992                                      build, offset, offset2);
1993           }
1994         else
1995           {
1996         */
1997         *offset += sizeof (UnionBlob);
1998         blob->discriminated = FALSE;
1999         blob->discriminator_type.offset = 0;
2000         
2001         members = g_list_copy (union_->members);
2002
2003         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
2004                                  node, build, offset, offset2);
2005
2006         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions,
2007                                  node, build, offset, offset2);
2008
2009         g_ir_node_check_unhandled_members (&members, node->type);
2010
2011         g_assert (members == NULL);
2012
2013         if (union_->discriminator_type)
2014           {
2015             for (l = union_->discriminators; l; l = l->next)
2016               {
2017                 GIrNode *member = (GIrNode *)l->data;
2018                 
2019                 g_ir_node_build_typelib (member, node, build, offset, offset2);
2020               }
2021           }
2022       }
2023       break;
2024
2025     case G_IR_NODE_ENUM:
2026     case G_IR_NODE_FLAGS:
2027       {
2028         EnumBlob *blob = (EnumBlob *)&data[*offset];
2029         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
2030
2031         *offset += sizeof (EnumBlob); 
2032
2033         if (node->type == G_IR_NODE_ENUM)
2034           blob->blob_type = BLOB_TYPE_ENUM;
2035         else
2036           blob->blob_type = BLOB_TYPE_FLAGS;
2037           
2038         blob->deprecated = enum_->deprecated;
2039         blob->reserved = 0;
2040         blob->storage_type = enum_->storage_type;
2041         blob->name = write_string (node->name, strings, data, offset2);
2042         if (enum_->gtype_name)
2043           {
2044             blob->unregistered = FALSE;
2045             blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
2046             blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
2047           }
2048         else
2049           {
2050             blob->unregistered = TRUE;
2051             blob->gtype_name = 0;
2052             blob->gtype_init = 0;
2053           }
2054
2055         blob->n_values = 0;
2056         blob->reserved2 = 0;
2057
2058         for (l = enum_->values; l; l = l->next)
2059           {
2060             GIrNode *value = (GIrNode *)l->data;
2061
2062             blob->n_values++;
2063             g_ir_node_build_typelib (value, node, build, offset, offset2);
2064           }
2065       }
2066       break;
2067       
2068     case G_IR_NODE_OBJECT:
2069       {
2070         ObjectBlob *blob = (ObjectBlob *)&data[*offset];
2071         GIrNodeInterface *object = (GIrNodeInterface *)node;
2072         GList *members;
2073
2074         blob->blob_type = BLOB_TYPE_OBJECT;
2075         blob->abstract = object->abstract;
2076         blob->deprecated = object->deprecated;
2077         blob->reserved = 0;
2078         blob->name = write_string (node->name, strings, data, offset2);
2079         blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
2080         blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
2081         if (object->parent)
2082           blob->parent = find_entry (module, modules, object->parent);
2083         else
2084           blob->parent = 0;
2085         if (object->glib_type_struct)
2086           blob->gtype_struct = find_entry (module, modules, object->glib_type_struct);
2087         else
2088           blob->gtype_struct = 0;
2089
2090         blob->n_interfaces = 0;
2091         blob->n_fields = 0;
2092         blob->n_properties = 0;
2093         blob->n_methods = 0;
2094         blob->n_signals = 0;
2095         blob->n_vfuncs = 0;
2096         blob->n_constants = 0;
2097         
2098         *offset += sizeof(ObjectBlob);
2099         for (l = object->interfaces; l; l = l->next)
2100           {
2101             blob->n_interfaces++;
2102             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
2103             *offset += 2;
2104           }
2105         
2106         members = g_list_copy (object->members);
2107
2108         *offset = ALIGN_VALUE (*offset, 4);
2109         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
2110                                  node, build, offset, offset2);
2111
2112         *offset = ALIGN_VALUE (*offset, 4);
2113         g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2114                                  node, build, offset, offset2);
2115
2116         *offset = ALIGN_VALUE (*offset, 4);
2117         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2118                                  node, build, offset, offset2);
2119
2120         *offset = ALIGN_VALUE (*offset, 4);
2121         g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2122                                  node, build, offset, offset2);
2123
2124         *offset = ALIGN_VALUE (*offset, 4);
2125         g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2126                                  node, build, offset, offset2);
2127
2128         *offset = ALIGN_VALUE (*offset, 4);
2129         g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2130                                  node, build, offset, offset2);
2131
2132         g_ir_node_check_unhandled_members (&members, node->type);
2133
2134         g_assert (members == NULL);
2135       }
2136       break;
2137
2138     case G_IR_NODE_INTERFACE:
2139       {
2140         InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
2141         GIrNodeInterface *iface = (GIrNodeInterface *)node;
2142         GList *members;
2143
2144         blob->blob_type = BLOB_TYPE_INTERFACE;
2145         blob->deprecated = iface->deprecated;
2146         blob->reserved = 0;
2147         blob->name = write_string (node->name, strings, data, offset2);
2148         blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
2149         blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
2150         if (iface->glib_type_struct)
2151           blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct);
2152         else
2153           blob->gtype_struct = 0;
2154         blob->n_prerequisites = 0;
2155         blob->n_properties = 0;
2156         blob->n_methods = 0;
2157         blob->n_signals = 0;
2158         blob->n_vfuncs = 0;
2159         blob->n_constants = 0;
2160         
2161         *offset += sizeof (InterfaceBlob);
2162         for (l = iface->prerequisites; l; l = l->next)
2163           {
2164             blob->n_prerequisites++;
2165             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
2166             *offset += 2;
2167           }
2168         
2169         members = g_list_copy (iface->members);
2170
2171         *offset = ALIGN_VALUE (*offset, 4);
2172         g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2173                                  node, build, offset, offset2);
2174
2175         *offset = ALIGN_VALUE (*offset, 4);
2176         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2177                                  node, build, offset, offset2);
2178
2179         *offset = ALIGN_VALUE (*offset, 4);
2180         g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2181                                  node, build, offset, offset2);
2182
2183         *offset = ALIGN_VALUE (*offset, 4);
2184         g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2185                                  node, build, offset, offset2);
2186
2187         *offset = ALIGN_VALUE (*offset, 4);
2188         g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2189                                  node, build, offset, offset2);
2190
2191         g_ir_node_check_unhandled_members (&members, node->type);
2192
2193         g_assert (members == NULL);
2194       }
2195       break;
2196
2197
2198     case G_IR_NODE_VALUE:
2199       {
2200         GIrNodeValue *value = (GIrNodeValue *)node;
2201         ValueBlob *blob = (ValueBlob *)&data[*offset];
2202         *offset += sizeof (ValueBlob);
2203
2204         blob->deprecated = value->deprecated;
2205         blob->reserved = 0;
2206         blob->name = write_string (node->name, strings, data, offset2);
2207         blob->value = value->value;
2208       }
2209       break;
2210
2211     case G_IR_NODE_ERROR_DOMAIN:
2212       {
2213         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
2214         ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
2215         *offset += sizeof (ErrorDomainBlob);
2216
2217         blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
2218         blob->deprecated = domain->deprecated;
2219         blob->reserved = 0;
2220         blob->name = write_string (node->name, strings, data, offset2);
2221         blob->get_quark = write_string (domain->getquark, strings, data, offset2);
2222         blob->error_codes = find_entry (module, modules, domain->codes);
2223         blob->reserved2 = 0;
2224       }
2225       break;
2226
2227     case G_IR_NODE_CONSTANT:
2228       {
2229         GIrNodeConstant *constant = (GIrNodeConstant *)node;
2230         ConstantBlob *blob = (ConstantBlob *)&data[*offset];
2231         guint32 pos;
2232
2233         pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type);
2234         *offset += sizeof (ConstantBlob);
2235
2236         blob->blob_type = BLOB_TYPE_CONSTANT;
2237         blob->deprecated = constant->deprecated;
2238         blob->reserved = 0;
2239         blob->name = write_string (node->name, strings, data, offset2);
2240
2241         blob->offset = *offset2;
2242         switch (constant->type->tag)
2243           {
2244           case GI_TYPE_TAG_BOOLEAN:
2245             blob->size = 4;
2246             *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
2247             break;
2248             case GI_TYPE_TAG_INT8:
2249             blob->size = 1;
2250               *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
2251             break;
2252           case GI_TYPE_TAG_UINT8:
2253             blob->size = 1;
2254             *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
2255             break;
2256           case GI_TYPE_TAG_INT16:
2257             blob->size = 2;
2258             *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
2259             break;
2260           case GI_TYPE_TAG_UINT16:
2261             blob->size = 2;
2262             *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
2263             break;
2264           case GI_TYPE_TAG_INT32:
2265             blob->size = 4;
2266             *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
2267             break;
2268           case GI_TYPE_TAG_UINT32:
2269             blob->size = 4;
2270             *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
2271             break;
2272           case GI_TYPE_TAG_INT64:
2273             blob->size = 8;
2274             *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
2275             break;
2276           case GI_TYPE_TAG_UINT64:
2277             blob->size = 8;
2278             *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
2279             break;
2280           case GI_TYPE_TAG_SHORT:
2281             blob->size = sizeof (gshort);
2282             *(gshort*)&data[blob->offset] = (gshort) parse_int_value (constant->value);
2283             break;
2284           case GI_TYPE_TAG_USHORT:
2285             blob->size = sizeof (gushort);
2286             *(gushort*)&data[blob->offset] = (gushort) parse_uint_value (constant->value);
2287             break;
2288           case GI_TYPE_TAG_INT:
2289             blob->size = sizeof (gint);
2290             *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
2291             break;
2292           case GI_TYPE_TAG_UINT:
2293             blob->size = sizeof (guint);
2294             *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
2295             break;
2296           case GI_TYPE_TAG_SSIZE: /* FIXME */
2297           case GI_TYPE_TAG_LONG:
2298             blob->size = sizeof (glong);
2299             *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
2300             break;
2301           case GI_TYPE_TAG_SIZE: /* FIXME */
2302           case GI_TYPE_TAG_TIME_T: 
2303           case GI_TYPE_TAG_ULONG:
2304             blob->size = sizeof (gulong);
2305             *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
2306             break;
2307           case GI_TYPE_TAG_FLOAT:
2308             blob->size = sizeof (gfloat);
2309             *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
2310             break;
2311           case GI_TYPE_TAG_DOUBLE:
2312             blob->size = sizeof (gdouble);
2313             *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
2314             break;
2315           case GI_TYPE_TAG_UTF8:
2316           case GI_TYPE_TAG_FILENAME:
2317             blob->size = strlen (constant->value) + 1;
2318             memcpy (&data[blob->offset], constant->value, blob->size);
2319             break;
2320           }
2321         *offset2 += ALIGN_VALUE (blob->size, 4);
2322         
2323         g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2);
2324       }
2325       break;
2326     default:
2327       g_assert_not_reached ();
2328     }
2329   
2330   g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d",
2331            node->name ? "'" : "",
2332            node->name ? node->name : "",
2333            node->name ? "' " : "",
2334            node, g_ir_node_type_to_string (node->type),
2335            old_offset, *offset, old_offset2, *offset2);
2336
2337   if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node))
2338     g_error ("exceeding space reservation; offset: %d (prev %d) offset2: %d (prev %d) nodesize: %d",
2339              *offset, old_offset, *offset2, old_offset2, g_ir_node_get_full_size (node));
2340 }
2341
2342 /* if str is already in the pool, return previous location, otherwise write str
2343  * to the typelib at offset, put it in the pool and update offset. If the 
2344  * typelib is not large enough to hold the string, reallocate it.
2345  */
2346 guint32 
2347 write_string (const gchar *str,
2348               GHashTable  *strings, 
2349               guchar      *data,
2350               guint32     *offset)
2351 {
2352   gpointer value;
2353   guint32 start;
2354
2355   string_count += 1;
2356   string_size += strlen (str);
2357
2358   value = g_hash_table_lookup (strings, str);
2359   
2360   if (value)
2361     return GPOINTER_TO_UINT (value);
2362
2363   unique_string_count += 1;
2364   unique_string_size += strlen (str);
2365
2366   g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset));
2367
2368   start = *offset;
2369   *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2370
2371   strcpy ((gchar*)&data[start], str);
2372   
2373   return start;
2374 }
2375