]> rtime.felk.cvut.cz Git - orte.git/blob - orte/idl-compiler/orte-idl-utils.c
New ORTE version 0.3.0 committed
[orte.git] / orte / idl-compiler / orte-idl-utils.c
1 //#include "config.h"
2 #include "orte-idl2.h"
3 #include <string.h>
4
5 void
6 orbit_idl_check_oneway_op (IDL_tree op)
7 {
8         g_assert (IDL_NODE_TYPE(op) == IDLN_OP_DCL);
9
10         if (IDL_OP_DCL (op).f_oneway) {
11                 IDL_tree sub;
12
13                 for (sub = IDL_OP_DCL (op).parameter_dcls; sub; sub = IDL_LIST (sub).next) {
14                         IDL_tree param = IDL_LIST (sub).data;
15
16                         if (IDL_PARAM_DCL (param).attr == IDL_PARAM_OUT ||
17                             IDL_PARAM_DCL (param).attr == IDL_PARAM_INOUT) {
18                                 g_warning ("Out or Inout parameter in declaration of oneway '%s'",
19                                            IDL_IDENT(IDL_OP_DCL(op).ident).str);
20                                 break;
21                         }
22                 }
23
24                 if (IDL_OP_DCL (op).op_type_spec)
25                         g_warning ("Return value in declaration of oneway '%s'",
26                                    IDL_IDENT(IDL_OP_DCL(op).ident).str);
27         }
28 }
29
30 void
31 orbit_idl_attr_fake_ops(IDL_tree attr, IDL_ns ns)
32 {
33   IDL_tree attr_name, ident, curnode, op1, op2, intf;
34   GString *attrname;
35   OIDL_Attr_Info *setme;
36
37   g_assert(attr && IDL_NODE_TYPE(attr) == IDLN_ATTR_DCL);
38
39   attrname = g_string_new(NULL);
40
41   for(curnode = IDL_ATTR_DCL(attr).simple_declarations; curnode; curnode = IDL_LIST(curnode).next) {
42     op1 = op2 = NULL;
43
44     attr_name = IDL_LIST(curnode).data;
45
46     g_string_printf(attrname, "_get_%s",
47                      IDL_IDENT(attr_name).str);
48     ident = IDL_ident_new(g_strdup(attrname->str));
49     IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
50     op1 = IDL_op_dcl_new(0, IDL_ATTR_DCL(attr).param_type_spec, ident, NULL, NULL, NULL);
51     IDL_NODE_UP(op1) = IDL_NODE_UP(attr);
52     intf = IDL_NODE_UP (IDL_NODE_UP (op1));
53     IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
54     IDL_ns_place_new(ns, ident);
55
56     if(!IDL_ATTR_DCL(attr).f_readonly) {
57       g_string_printf(attrname, "_set_%s",
58                        IDL_IDENT(attr_name).str);
59       ident = IDL_ident_new(g_strdup(attrname->str));
60       IDL_IDENT_TO_NS(ident) = IDL_IDENT_TO_NS(attr_name);
61       op2 = IDL_op_dcl_new(0, NULL, ident, NULL, NULL, NULL);
62       IDL_NODE_UP(op2) = IDL_NODE_UP(attr);
63       intf = IDL_NODE_UP (IDL_NODE_UP (op2));
64       IDL_NS(ns).current = IDL_IDENT_TO_NS (IDL_INTERFACE (intf).ident);
65       IDL_ns_place_new(ns, ident);
66       IDL_OP_DCL(op2).parameter_dcls = IDL_list_new(
67                                                     IDL_param_dcl_new(IDL_PARAM_IN,
68                                                                       IDL_ATTR_DCL(attr).param_type_spec,
69                                                                       IDL_ident_new(g_strdup("value"))));
70     }
71
72     setme = g_new0(OIDL_Attr_Info, 1);
73     setme->op1 = op1;
74     setme->op2 = op2;
75     attr_name->data = setme;
76   }
77
78   g_string_free(attrname, TRUE);
79 }
80
81 #define INDENT_INCREMENT_1 2
82 #define INDENT_INCREMENT_2 4
83
84 static void do_indent(int level) {
85   int i;
86   for(i = 0; i < level; i++) g_print(" ");
87 }
88
89 static const char * const nodenames[] = {
90   "DATUM",
91   "LOOP",
92   "SWITCH",
93   "CASE",
94   "COMPLEX",
95   "CONST",
96   "SET",
97   NULL
98 };
99
100 void
101 orbit_idl_print_node(IDL_tree node, int indent_level)
102 {
103   IDL_tree curnode;
104   char *s;
105
106   do_indent(indent_level);
107
108   if(node == NULL) {
109     g_print("(null)\n");
110     return;
111   }
112
113   g_print("[%d] ", IDL_NODE_REFS(node));
114
115   switch(IDL_NODE_TYPE(node)) {
116
117   case IDLN_NONE:
118     g_print("NONE\n");
119     break;
120
121   case IDLN_LIST:
122     g_print("LIST:\n");
123     for(curnode = node; curnode;
124         curnode = IDL_LIST(curnode).next) {
125       orbit_idl_print_node(IDL_LIST(curnode).data, indent_level + INDENT_INCREMENT_1);
126     }
127     break;
128
129   case IDLN_GENTREE:
130     break;
131
132   case IDLN_INTEGER:
133     g_print("INTEGER: %" IDL_LL "d\n", IDL_INTEGER(node).value);
134     break;
135
136   case IDLN_STRING:
137     g_print("STRING: %s\n", IDL_STRING(node).value);
138     break;
139
140   case IDLN_WIDE_STRING:
141     g_print("WIDE STRING: %ls\n", IDL_WIDE_STRING(node).value);
142     break;
143
144   case IDLN_CHAR:
145     g_print("CHAR: %s\n", IDL_CHAR(node).value);
146     break;
147
148   case IDLN_WIDE_CHAR:
149     g_print("WIDE CHAR: %ls\n", IDL_WIDE_CHAR(node).value);
150     break;
151
152   case IDLN_FIXED:
153     g_print("FIXED: %s\n", IDL_FIXED(node).value);
154     break;
155
156   case IDLN_FLOAT:
157     g_print("FLOAT: %f\n", IDL_FLOAT(node).value);
158     break;
159
160   case IDLN_BOOLEAN:
161     g_print("BOOLEAN: %s\n", (IDL_BOOLEAN(node).value)?"True":"False");
162     break;
163
164   case IDLN_IDENT:
165     s = IDL_ns_ident_to_qstring(IDL_IDENT_TO_NS(node), "_", 0);
166     g_print("IDENT: %s NSQ: %s RID: \"%s\"\n",
167             IDL_IDENT(node).str, s,
168             IDL_IDENT_REPO_ID(node) ? IDL_IDENT_REPO_ID(node) : "");
169     g_free(s);
170     break;
171
172   case IDLN_TYPE_DCL:
173     g_print("TYPE DCL:\n");
174     orbit_idl_print_node(IDL_TYPE_DCL(node).type_spec, indent_level + INDENT_INCREMENT_1);
175     do_indent(indent_level + INDENT_INCREMENT_1); g_print("decls:\n");
176     orbit_idl_print_node(IDL_TYPE_DCL(node).dcls, indent_level + INDENT_INCREMENT_2);
177     break;
178
179   case IDLN_CONST_DCL:
180     g_print("CONST DCL:\n");
181     orbit_idl_print_node(IDL_CONST_DCL(node).const_type, indent_level + INDENT_INCREMENT_1);
182     do_indent(indent_level + INDENT_INCREMENT_1); g_print("ident:\n");
183     orbit_idl_print_node(IDL_CONST_DCL(node).ident, indent_level + INDENT_INCREMENT_2);
184     do_indent(indent_level + INDENT_INCREMENT_1); g_print("const_exp:\n");
185     orbit_idl_print_node(IDL_CONST_DCL(node).const_exp, indent_level + INDENT_INCREMENT_2);
186     break;
187
188   case IDLN_EXCEPT_DCL:
189     g_print("EXCEPT DCL:\n");
190     orbit_idl_print_node(IDL_EXCEPT_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
191     do_indent(indent_level + INDENT_INCREMENT_1); g_print("members:\n");
192     orbit_idl_print_node(IDL_EXCEPT_DCL(node).members, indent_level + INDENT_INCREMENT_2);
193     break;
194
195   case IDLN_ATTR_DCL:
196     g_print("ATTR_DCL (%s):\n", (IDL_ATTR_DCL(node).f_readonly)?"readonly":"rw");
197     orbit_idl_print_node(IDL_ATTR_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
198     do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarations:\n");
199     orbit_idl_print_node(IDL_ATTR_DCL(node).simple_declarations, indent_level + INDENT_INCREMENT_2);
200     break;
201
202   case IDLN_OP_DCL:
203     g_print("OP DCL (%s):\n", (IDL_OP_DCL(node).f_oneway)?"oneway":"normal");
204     orbit_idl_print_node(IDL_OP_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
205     do_indent(indent_level + INDENT_INCREMENT_1); g_print("op_type_spec:\n");
206     orbit_idl_print_node(IDL_OP_DCL(node).op_type_spec, indent_level + INDENT_INCREMENT_2);
207     do_indent(indent_level + INDENT_INCREMENT_1); g_print("parameter_dcls:\n");
208     orbit_idl_print_node(IDL_OP_DCL(node).parameter_dcls, indent_level + INDENT_INCREMENT_2);
209     do_indent(indent_level + INDENT_INCREMENT_1); g_print("raises_expr:\n");
210     orbit_idl_print_node(IDL_OP_DCL(node).raises_expr, indent_level + INDENT_INCREMENT_2);
211     do_indent(indent_level + INDENT_INCREMENT_1); g_print("context_expr:\n");
212     orbit_idl_print_node(IDL_OP_DCL(node).context_expr, indent_level + INDENT_INCREMENT_2);
213     break;
214
215   case IDLN_PARAM_DCL:
216     g_print("PARAM DCL: ");
217     switch(IDL_PARAM_DCL(node).attr) {
218     case IDL_PARAM_IN: g_print("(in)\n"); break;
219     case IDL_PARAM_OUT: g_print("(out)\n"); break;
220     case IDL_PARAM_INOUT: g_print("(inout)\n"); break;
221     }
222     orbit_idl_print_node(IDL_PARAM_DCL(node).param_type_spec, indent_level + INDENT_INCREMENT_1);
223     do_indent(indent_level + INDENT_INCREMENT_1); g_print("simple_declarator:\n");
224     orbit_idl_print_node(IDL_PARAM_DCL(node).simple_declarator, indent_level + INDENT_INCREMENT_2);
225     break;
226   case IDLN_FORWARD_DCL:
227     g_print("FORWARD DCL:\n");
228     orbit_idl_print_node(IDL_FORWARD_DCL(node).ident, indent_level + INDENT_INCREMENT_1);
229     break;
230   case IDLN_INTERFACE:
231     g_print("INTERFACE:\n");
232     orbit_idl_print_node(IDL_INTERFACE(node).ident, indent_level + INDENT_INCREMENT_1);
233     do_indent(indent_level + INDENT_INCREMENT_1); g_print("inheritance_spec:\n");
234     orbit_idl_print_node(IDL_INTERFACE(node).inheritance_spec, indent_level + INDENT_INCREMENT_2);
235     do_indent(indent_level + INDENT_INCREMENT_1); g_print("body:\n");
236     orbit_idl_print_node(IDL_INTERFACE(node).body, indent_level + INDENT_INCREMENT_2);
237     break;
238   case IDLN_MODULE:
239     g_print("MODULE:\n");
240     orbit_idl_print_node(IDL_MODULE(node).ident, indent_level + INDENT_INCREMENT_1);
241     do_indent(indent_level + INDENT_INCREMENT_1); g_print("definition_list:\n");
242     orbit_idl_print_node(IDL_MODULE(node).definition_list, indent_level + INDENT_INCREMENT_2);
243     break;
244
245   case IDLN_TYPE_INTEGER:
246     if(!IDL_TYPE_INTEGER(node).f_signed) g_print("TYPE unsigned ");
247     switch(IDL_TYPE_INTEGER(node).f_type) {
248     case IDL_INTEGER_TYPE_SHORT: g_print("short\n"); break;
249     case IDL_INTEGER_TYPE_LONG: g_print("long\n"); break;
250     case IDL_INTEGER_TYPE_LONGLONG: g_print("long long\n"); break;
251     }
252     break;
253   case IDLN_TYPE_FLOAT:
254     switch(IDL_TYPE_FLOAT(node).f_type) {
255     case IDL_FLOAT_TYPE_FLOAT: g_print("TYPE float\n"); break;
256     case IDL_FLOAT_TYPE_DOUBLE: g_print("TYPE double\n"); break;
257     case IDL_FLOAT_TYPE_LONGDOUBLE: g_print("TYPE long double\n"); break;
258     }
259     break;
260   case IDLN_TYPE_FIXED:
261     g_print("TYPE fixed:\n");
262     orbit_idl_print_node(IDL_TYPE_FIXED(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
263     orbit_idl_print_node(IDL_TYPE_FIXED(node).integer_lit, indent_level + INDENT_INCREMENT_1);
264     break;
265   case IDLN_TYPE_STRING:
266     g_print("TYPE string:\n");
267     orbit_idl_print_node(IDL_TYPE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
268     break;
269   case IDLN_TYPE_WIDE_STRING:
270     g_print("TYPE wide string:\n");
271     orbit_idl_print_node(IDL_TYPE_WIDE_STRING(node).positive_int_const, indent_level + INDENT_INCREMENT_1);
272     break;
273   case IDLN_TYPE_ENUM:
274     g_print("TYPE enum:\n");
275     orbit_idl_print_node(IDL_TYPE_ENUM(node).ident, indent_level + INDENT_INCREMENT_1);
276     do_indent(indent_level + INDENT_INCREMENT_1); g_print("enumerator_list:\n");
277     orbit_idl_print_node(IDL_TYPE_ENUM(node).enumerator_list, indent_level + INDENT_INCREMENT_2);
278     break;
279   case IDLN_TYPE_ARRAY:
280     g_print("TYPE array:\n");
281     orbit_idl_print_node(IDL_TYPE_ARRAY(node).ident, indent_level + INDENT_INCREMENT_1);
282     do_indent(indent_level + INDENT_INCREMENT_1); g_print("size_list:\n");
283     orbit_idl_print_node(IDL_TYPE_ARRAY(node).size_list, indent_level + INDENT_INCREMENT_2);
284     break;
285   case IDLN_TYPE_SEQUENCE:
286     g_print("TYPE sequence:\n");
287     orbit_idl_print_node(IDL_TYPE_SEQUENCE(node).simple_type_spec, indent_level + INDENT_INCREMENT_1);
288     do_indent(indent_level + INDENT_INCREMENT_1); g_print("positive_int_const:\n");
289     orbit_idl_print_node(IDL_TYPE_SEQUENCE(node).positive_int_const, indent_level + INDENT_INCREMENT_2);
290     break;
291   case IDLN_TYPE_STRUCT:
292     g_print("TYPE struct:\n");
293     orbit_idl_print_node(IDL_TYPE_STRUCT(node).ident, indent_level + INDENT_INCREMENT_1);
294     do_indent(indent_level + INDENT_INCREMENT_1); g_print("member_list:\n");
295     orbit_idl_print_node(IDL_TYPE_STRUCT(node).member_list, indent_level + INDENT_INCREMENT_2);
296     break;
297   case IDLN_TYPE_UNION:
298     g_print("TYPE union:\n");
299     orbit_idl_print_node(IDL_TYPE_UNION(node).ident, indent_level + INDENT_INCREMENT_1);
300     do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_type_spec:\n");
301     orbit_idl_print_node(IDL_TYPE_UNION(node).switch_type_spec, indent_level + INDENT_INCREMENT_2);
302     do_indent(indent_level + INDENT_INCREMENT_1); g_print("switch_body:\n");
303     orbit_idl_print_node(IDL_TYPE_UNION(node).switch_body, indent_level + INDENT_INCREMENT_2);
304     break;
305   case IDLN_MEMBER:
306     g_print("MEMBER:\n");
307     orbit_idl_print_node(IDL_MEMBER(node).type_spec, indent_level + INDENT_INCREMENT_1);
308     do_indent(indent_level + INDENT_INCREMENT_1); g_print("dcls:\n");
309     orbit_idl_print_node(IDL_MEMBER(node).dcls, indent_level + INDENT_INCREMENT_2);
310     break;
311   case IDLN_CASE_STMT:
312     g_print("CASE_STMT:\n");
313     orbit_idl_print_node(IDL_CASE_STMT(node).labels, indent_level + INDENT_INCREMENT_1);
314     do_indent(indent_level + INDENT_INCREMENT_1); g_print("element_spec:\n");
315     orbit_idl_print_node(IDL_CASE_STMT(node).element_spec, indent_level + INDENT_INCREMENT_2);
316     break;
317   case IDLN_BINOP:
318     g_print("BINOP ");
319     switch(IDL_BINOP(node).op) {
320     case IDL_BINOP_OR: g_print("or:\n"); break;
321     case IDL_BINOP_XOR: g_print("xor:\n"); break;
322     case IDL_BINOP_AND: g_print("and:\n"); break;
323     case IDL_BINOP_SHR: g_print("shr:\n"); break;
324     case IDL_BINOP_SHL: g_print("shl:\n"); break;
325     case IDL_BINOP_ADD: g_print("add:\n"); break;
326     case IDL_BINOP_SUB: g_print("sub:\n"); break;
327     case IDL_BINOP_MULT: g_print("mult:\n"); break;
328     case IDL_BINOP_DIV: g_print("div:\n"); break;
329     case IDL_BINOP_MOD: g_print("mod:\n"); break;
330     }
331     do_indent(indent_level + INDENT_INCREMENT_1); g_print("left:\n");
332     orbit_idl_print_node(IDL_BINOP(node).left, indent_level + INDENT_INCREMENT_2);
333     do_indent(indent_level + INDENT_INCREMENT_1); g_print("right:\n");
334     orbit_idl_print_node(IDL_BINOP(node).right, indent_level + INDENT_INCREMENT_2);
335     break;
336   case IDLN_UNARYOP:
337     g_print("UNARYOP ");
338     switch(IDL_UNARYOP(node).op) {
339     case IDL_UNARYOP_PLUS: g_print("plus:\n"); break;
340     case IDL_UNARYOP_MINUS: g_print("minus:\n"); break;
341     case IDL_UNARYOP_COMPLEMENT: g_print("complement:\n"); break;
342     }
343     orbit_idl_print_node(IDL_UNARYOP(node).operand, indent_level + INDENT_INCREMENT_1);
344     break;
345   case IDLN_TYPE_CHAR:
346     g_print("TYPE char\n");
347     break;
348   case IDLN_TYPE_WIDE_CHAR:
349     g_print("TYPE wide char\n");
350     break;
351   case IDLN_TYPE_BOOLEAN:
352     g_print("TYPE boolean\n");
353     break;
354   case IDLN_TYPE_OCTET:
355     g_print("TYPE octet\n");
356     break;
357   case IDLN_TYPE_OBJECT:
358     g_print("TYPE object\n");
359     break;
360   case IDLN_TYPE_ANY:
361     g_print("TYPE any\n");
362     break;
363   case IDLN_TYPE_TYPECODE:
364     g_print("TYPE TypeCode\n");
365     break;
366   case IDLN_CODEFRAG:
367     g_print("CODEFRAG\n");
368     break;
369   default:
370     g_print("unhandled %d\n", IDL_NODE_TYPE(node));
371   }
372 }
373
374 static void
375 IDL_tree_traverse_helper(IDL_tree p, GFunc f,
376                          gconstpointer func_data,
377                          GHashTable *visited_nodes,
378                          gboolean    include_self)
379 {
380         IDL_tree curitem;
381
382         if (g_hash_table_lookup (visited_nodes, p))
383                 return;
384
385         g_hash_table_insert (visited_nodes, p, ((gpointer)1));
386
387         for (curitem = IDL_INTERFACE (p).inheritance_spec; curitem;
388              curitem = IDL_LIST (curitem).next) {
389                 IDL_tree_traverse_helper (IDL_get_parent_node 
390                         (IDL_LIST (curitem).data, IDLN_INTERFACE, NULL), f, func_data, visited_nodes, TRUE);
391         }
392
393         if (include_self)
394                 f(p, (gpointer)func_data);
395 }
396
397 void
398 IDL_tree_traverse_parents_full (IDL_tree      p,
399                                 GFunc         f,
400                                 gconstpointer func_data,
401                                 gboolean      include_self)
402 {
403         GHashTable *visited_nodes = g_hash_table_new (NULL, g_direct_equal);
404
405         if (!(p && f))
406                 return;
407
408         if (IDL_NODE_TYPE(p) != IDLN_INTERFACE)
409                 p = IDL_get_parent_node (p, IDLN_INTERFACE, NULL);
410
411         if (!p)
412                 return;
413
414         IDL_tree_traverse_helper (p, f, func_data, visited_nodes, include_self);
415
416         g_hash_table_destroy (visited_nodes);
417 }
418
419 void
420 IDL_tree_traverse_parents (IDL_tree p,
421                            GFunc f,
422                            gconstpointer func_data)
423 {
424         IDL_tree_traverse_parents_full (p, f, func_data, TRUE);
425 }
426
427 /* For use by below function */
428 static const int * const
429 orbit_cbe_get_typeoffsets_table (void)
430 {
431   static int typeoffsets[IDLN_LAST];
432   static gboolean initialized = FALSE;
433   
434   if (!initialized) {
435     int i;
436
437     for (i = 0; i < IDLN_LAST; ++i)
438       typeoffsets[i] = -1;
439
440     typeoffsets[IDLN_FORWARD_DCL] = 8; /* (same as objref) */
441     typeoffsets[IDLN_TYPE_INTEGER] = 0;
442     typeoffsets[IDLN_TYPE_FLOAT] = 0;
443     typeoffsets[IDLN_TYPE_FIXED] = 3;
444     typeoffsets[IDLN_TYPE_CHAR] = 5;
445     typeoffsets[IDLN_TYPE_WIDE_CHAR] = 6;
446     typeoffsets[IDLN_TYPE_STRING] = 12;
447     typeoffsets[IDLN_TYPE_WIDE_STRING] = 13;
448     typeoffsets[IDLN_TYPE_BOOLEAN] = 4;
449     typeoffsets[IDLN_TYPE_OCTET] = 7;
450     typeoffsets[IDLN_TYPE_ANY] = 16;
451     typeoffsets[IDLN_TYPE_OBJECT] = 9;
452     typeoffsets[IDLN_TYPE_TYPECODE] = 9;
453     typeoffsets[IDLN_TYPE_ENUM] = 8;
454     typeoffsets[IDLN_TYPE_SEQUENCE] = 14;
455     typeoffsets[IDLN_TYPE_ARRAY] = 15;
456     typeoffsets[IDLN_TYPE_STRUCT] = 10;
457     typeoffsets[IDLN_TYPE_UNION] = 11;
458     typeoffsets[IDLN_NATIVE] = 15; /* no pointers ever, same as fixed array */
459     typeoffsets[IDLN_INTERFACE] = 9; /* (same as objref) */
460     
461     initialized = TRUE;
462   }
463   
464   return typeoffsets;
465 }
466
467
468 /**
469         This is a rather hairy function. Its purpose is to output the
470         required number of *'s that indicate the amount of indirection
471         for input, output, & input-output parameters, and return
472         values.  We do this by having a table of the number of *'s for
473         each type and purpose (nptrrefs_required), taken from 19.20
474         of the CORBA 2.2 spec, and then having a table that translates
475         from the IDLN_* enums into an index into nptrrefs_required (typeoffsets)
476 **/
477 gint
478 oidl_param_info(IDL_tree in_param, IDL_ParamRole role, gboolean *isSlice)
479 {
480         IDL_tree param;
481         const int * const typeoffsets = orbit_cbe_get_typeoffsets_table ();
482         const int nptrrefs_required[][4] = {
483                 {0,1,1,0} /* float */,
484                 {0,1,1,0} /* double */,
485                 {0,1,1,0} /* long double */,
486                 {1,1,1,0} /* fixed_d_s 3 */, 
487                 {0,1,1,0} /* boolean */,
488                 {0,1,1,0} /* char */,
489                 {0,1,1,0} /* wchar */,
490                 {0,1,1,0} /* octet */,
491                 {0,1,1,0} /* enum */,
492                 {0,1,1,0} /* objref */,
493                 {1,1,1,0} /* fixed struct 10 */,
494                 {1,1,1,0} /* fixed union */,
495                 {0,1,1,0} /* string */,
496                 {0,1,1,0} /* wstring */,
497                 {1,1,2,1} /* sequence */,
498                 {0,0,0,0} /* fixed array */,
499                 {1,1,2,1} /* any 16 */
500         };
501         int retval = 0;
502         int typeidx;
503
504         *isSlice = FALSE;
505
506         if(!in_param)
507                 return 0; /* void */
508
509         /* Now, how do we use this table? :) */
510         param = orbit_cbe_get_typespec (in_param);
511
512         g_assert (param);
513
514         switch (IDL_NODE_TYPE (param)) {
515         case IDLN_TYPE_STRUCT:
516         case IDLN_TYPE_UNION:
517                 if (((role == DATA_RETURN) || (role == DATA_OUT)) &&
518                     !orbit_cbe_type_is_fixed_length(param))
519                         retval++;
520                 break;
521
522         case IDLN_TYPE_ARRAY:
523                 if ( role == DATA_RETURN ) {
524                         *isSlice = TRUE;
525                         retval = 1;
526
527                 } else if (role == DATA_OUT &&
528                            !orbit_cbe_type_is_fixed_length (param)) {
529                         *isSlice = TRUE;
530                         retval = 2;
531                 }
532                 break;
533
534         case IDLN_NATIVE:
535                 if ( IDL_NATIVE (param).user_type
536                      && strcmp (IDL_NATIVE (param).user_type,
537                                 "IDL_variable_length_struct") == 0 )
538                         return role == DATA_OUT ? 2 : 1;
539                 break;
540
541         case IDLN_EXCEPT_DCL:
542                 fprintf (stderr, "Error: exception declared at '%s:%d' cannot be "
543                          "used as a method parameter\n", in_param->_file,
544                          in_param->_line);
545                 exit (1);
546                 break;
547         default:
548                 break;
549         }
550
551         /* ERROR ! */
552         typeidx = typeoffsets [IDL_NODE_TYPE (param)];
553         g_assert (typeidx >= 0);
554
555         switch (role) {
556         case DATA_IN:
557                 role = 0;
558                 break;
559         case DATA_INOUT:
560                 role = 1;
561                 break;
562         case DATA_OUT:
563                 role = 2;
564                 break;
565         case DATA_RETURN:
566                 role = 3;
567                 break;
568         default:
569                 g_assert_not_reached ();
570                 break;
571         }
572
573         retval += nptrrefs_required [typeidx] [role];
574
575         return retval;
576 }
577
578 /**
579     Fixed-length-ness is a property that CORBA defines, and it is
580     a property of each type, not each kind.  Furthermore, it doesnt
581     depend on the language mapping. Generally, the GIOP coding
582     a fixed length variable will be a known length (determined by the TC),
583     regardless of the data within the variable.
584
585     With the C mapping, fixed --> nothing to free in this node
586     Note that in the C mapping, everything is a struct and is
587     fixed length in that sense. Thus variable length types show
588     up in C as pointers.
589
590     Recursive types introduced by sequences are not a problem for this
591     func, because sequences are not fixed length, and terminate
592     the recursion.
593 **/
594  
595 gboolean
596 orbit_cbe_type_is_fixed_length(IDL_tree ts)
597 {
598   gboolean is_fixed = TRUE;
599   IDL_tree curitem;
600
601   ts = orbit_cbe_get_typespec(ts);
602   switch(IDL_NODE_TYPE(ts)) {
603   case IDLN_TYPE_FLOAT:
604   case IDLN_TYPE_INTEGER:
605   case IDLN_TYPE_ENUM:
606   case IDLN_TYPE_CHAR:
607   case IDLN_TYPE_WIDE_CHAR:
608   case IDLN_TYPE_OCTET:
609   case IDLN_TYPE_BOOLEAN:
610     return TRUE;
611     break;
612   case IDLN_TYPE_SEQUENCE:
613   case IDLN_TYPE_STRING:
614   case IDLN_TYPE_WIDE_STRING:
615   case IDLN_TYPE_OBJECT:
616   case IDLN_FORWARD_DCL:
617   case IDLN_INTERFACE:
618   case IDLN_TYPE_ANY:
619   case IDLN_NATIVE:
620   case IDLN_TYPE_TYPECODE:
621     return FALSE;
622     break;
623   case IDLN_TYPE_UNION:
624     for(curitem = IDL_TYPE_UNION(ts).switch_body; curitem;
625         curitem = IDL_LIST(curitem).next) {
626       is_fixed &= orbit_cbe_type_is_fixed_length(IDL_LIST(IDL_CASE_STMT(IDL_LIST(curitem).data).element_spec).data);
627     }
628     return is_fixed;
629     break;
630   case IDLN_EXCEPT_DCL:
631   case IDLN_TYPE_STRUCT:
632     for(curitem = IDL_TYPE_STRUCT(ts).member_list; curitem;
633         curitem = IDL_LIST(curitem).next) {
634       is_fixed &= orbit_cbe_type_is_fixed_length(IDL_LIST(curitem).data);
635     }
636     return is_fixed;
637     break;
638   case IDLN_TYPE_ARRAY:
639     return orbit_cbe_type_is_fixed_length(IDL_TYPE_DCL(IDL_get_parent_node(ts, IDLN_TYPE_DCL, NULL)).type_spec);
640     break;
641   case IDLN_TYPE_DCL:
642     return orbit_cbe_type_is_fixed_length(IDL_TYPE_DCL(ts).type_spec);
643     break;
644   case IDLN_IDENT:
645   case IDLN_LIST:
646     return orbit_cbe_type_is_fixed_length(IDL_NODE_UP(ts));
647     break;
648   case IDLN_MEMBER:
649     return orbit_cbe_type_is_fixed_length(IDL_MEMBER(ts).type_spec);
650     break;
651   default:
652     g_warning("I'm not sure if type %s is fixed-length", IDL_tree_type_names[IDL_NODE_TYPE(ts)]);
653     return FALSE;
654   }
655 }
656
657 IDL_tree
658 orbit_cbe_get_typespec(IDL_tree node)
659 {
660   if(node == NULL)
661     return NULL;
662
663   switch(IDL_NODE_TYPE(node)) {
664   case IDLN_TYPE_INTEGER:
665   case IDLN_TYPE_FLOAT:
666   case IDLN_TYPE_FIXED:
667   case IDLN_TYPE_CHAR:
668   case IDLN_TYPE_WIDE_CHAR:
669   case IDLN_TYPE_STRING:
670   case IDLN_TYPE_WIDE_STRING:
671   case IDLN_TYPE_BOOLEAN:
672   case IDLN_TYPE_OCTET:
673   case IDLN_TYPE_ANY:
674   case IDLN_TYPE_OBJECT:
675   case IDLN_TYPE_ENUM:
676   case IDLN_TYPE_SEQUENCE:
677   case IDLN_TYPE_ARRAY:
678   case IDLN_TYPE_STRUCT:
679   case IDLN_TYPE_UNION:
680   case IDLN_EXCEPT_DCL:
681   case IDLN_FORWARD_DCL:
682   case IDLN_INTERFACE:
683   case IDLN_NATIVE:
684   case IDLN_TYPE_TYPECODE:
685     return node;
686     break;
687   case IDLN_TYPE_DCL:
688     return orbit_cbe_get_typespec(IDL_TYPE_DCL(node).type_spec);
689     break;
690   case IDLN_PARAM_DCL:
691     return orbit_cbe_get_typespec(IDL_PARAM_DCL(node).param_type_spec);
692     break;
693   case IDLN_MEMBER:
694     return orbit_cbe_get_typespec(IDL_MEMBER(node).type_spec);
695     break;
696   case IDLN_LIST:
697   case IDLN_IDENT:
698     return orbit_cbe_get_typespec(IDL_get_parent_node(node, IDLN_ANY, NULL));
699     break;
700   default:
701     g_error("Unhandled node type %s!", IDL_tree_type_names[IDL_NODE_TYPE(node)]);
702     return NULL;
703   }
704 }
705
706 IDL_ParamRole
707 oidl_attr_to_paramrole(enum IDL_param_attr attr)
708 {
709   switch(attr) {
710   case IDL_PARAM_IN:
711     return DATA_IN;
712   case IDL_PARAM_OUT:
713     return DATA_OUT;
714   case IDL_PARAM_INOUT:
715     return DATA_INOUT;
716   default:
717     g_warning("Unknown IDL_param_attr %d", attr);
718     return -1;
719   }
720 }