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