xref: /reactos/sdk/tools/widl/typetree.c (revision 40462c92)
1 /*
2  * IDL Type Tree
3  *
4  * Copyright 2008 Robert Shearman
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.1 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 Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "config.h"
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "widl.h"
28 #include "utils.h"
29 #include "parser.h"
30 #include "typetree.h"
31 #include "header.h"
32 
33 type_t *duptype(type_t *t, int dupname)
34 {
35   type_t *d = alloc_type();
36 
37   *d = *t;
38   if (dupname && t->name)
39     d->name = xstrdup(t->name);
40 
41   return d;
42 }
43 
44 type_t *make_type(enum type_type type)
45 {
46     type_t *t = alloc_type();
47     t->name = NULL;
48     t->namespace = NULL;
49     t->type_type = type;
50     t->attrs = NULL;
51     t->c_name = NULL;
52     t->orig = NULL;
53     memset(&t->details, 0, sizeof(t->details));
54     t->typestring_offset = 0;
55     t->ptrdesc = 0;
56     t->ignore = (parse_only != 0);
57     t->defined = FALSE;
58     t->written = FALSE;
59     t->user_types_registered = FALSE;
60     t->tfswrite = FALSE;
61     t->checked = FALSE;
62     t->is_alias = FALSE;
63     t->typelib_idx = -1;
64     init_loc_info(&t->loc_info);
65     return t;
66 }
67 
68 static const var_t *find_arg(const var_list_t *args, const char *name)
69 {
70     const var_t *arg;
71 
72     if (args) LIST_FOR_EACH_ENTRY(arg, args, const var_t, entry)
73     {
74         if (arg->name && !strcmp(name, arg->name))
75             return arg;
76     }
77 
78     return NULL;
79 }
80 
81 const char *type_get_name(const type_t *type, enum name_type name_type)
82 {
83     switch(name_type) {
84     case NAME_DEFAULT:
85         return type->name;
86     case NAME_C:
87         return type->c_name;
88     }
89 
90     assert(0);
91     return NULL;
92 }
93 
94 static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator)
95 {
96     if(is_global_namespace(namespace)) {
97         if(!use_abi_namespace)
98             return ptr;
99         strcpy(ptr, "ABI");
100         strcat(ptr, separator);
101         return ptr + strlen(ptr);
102     }
103 
104     ptr = append_namespace(ptr, namespace->parent, separator);
105     strcpy(ptr, namespace->name);
106     strcat(ptr, separator);
107     return ptr + strlen(ptr);
108 }
109 
110 char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix)
111 {
112     unsigned len = strlen(prefix) + strlen(suffix);
113     unsigned sep_len = strlen(separator);
114     struct namespace *iter;
115     char *ret, *ptr;
116 
117     if(use_abi_namespace && !is_global_namespace(namespace))
118         len += 3 /* strlen("ABI") */ + sep_len;
119 
120     for(iter = namespace; !is_global_namespace(iter); iter = iter->parent)
121         len += strlen(iter->name) + sep_len;
122 
123     ret = xmalloc(len+1);
124     strcpy(ret, prefix);
125     ptr = append_namespace(ret + strlen(ret), namespace, separator);
126     strcpy(ptr, suffix);
127 
128     return ret;
129 }
130 
131 type_t *type_new_function(var_list_t *args)
132 {
133     var_t *arg;
134     type_t *t;
135     unsigned int i = 0;
136 
137     if (args)
138     {
139         arg = LIST_ENTRY(list_head(args), var_t, entry);
140         if (list_count(args) == 1 && !arg->name && arg->type && type_get_type(arg->type) == TYPE_VOID)
141         {
142             list_remove(&arg->entry);
143             free(arg);
144             free(args);
145             args = NULL;
146         }
147     }
148     if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
149     {
150         if (arg->type && type_get_type(arg->type) == TYPE_VOID)
151             error_loc("argument '%s' has void type\n", arg->name);
152         if (!arg->name)
153         {
154             if (i > 26 * 26)
155                 error_loc("too many unnamed arguments\n");
156             else
157             {
158                 int unique;
159                 do
160                 {
161                     char name[3];
162                     name[0] = i > 26 ? 'a' + i / 26 : 'a' + i;
163                     name[1] = i > 26 ? 'a' + i % 26 : 0;
164                     name[2] = 0;
165                     unique = !find_arg(args, name);
166                     if (unique)
167                         arg->name = xstrdup(name);
168                     i++;
169                 } while (!unique);
170             }
171         }
172     }
173 
174     t = make_type(TYPE_FUNCTION);
175     t->details.function = xmalloc(sizeof(*t->details.function));
176     t->details.function->args = args;
177     t->details.function->idx = -1;
178     return t;
179 }
180 
181 type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
182 {
183     type_t *t = make_type(TYPE_POINTER);
184     t->details.pointer.def_fc = pointer_default;
185     t->details.pointer.ref = ref;
186     t->attrs = attrs;
187     return t;
188 }
189 
190 type_t *type_new_alias(type_t *t, const char *name)
191 {
192     type_t *a = duptype(t, 0);
193 
194     a->name = xstrdup(name);
195     a->attrs = NULL;
196     a->orig = t;
197     a->is_alias = TRUE;
198     /* for pointer types */
199     a->details = t->details;
200     init_loc_info(&a->loc_info);
201 
202     return a;
203 }
204 
205 type_t *type_new_module(char *name)
206 {
207     type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
208     if (type->type_type != TYPE_MODULE || type->defined)
209         error_loc("%s: redefinition error; original definition was at %s:%d\n",
210                   type->name, type->loc_info.input_name, type->loc_info.line_number);
211     type->name = name;
212     return type;
213 }
214 
215 type_t *type_new_coclass(char *name)
216 {
217     type_t *type = get_type(TYPE_COCLASS, name, NULL, 0);
218     if (type->type_type != TYPE_COCLASS || type->defined)
219         error_loc("%s: redefinition error; original definition was at %s:%d\n",
220                   type->name, type->loc_info.input_name, type->loc_info.line_number);
221     type->name = name;
222     return type;
223 }
224 
225 
226 type_t *type_new_array(const char *name, type_t *element, int declptr,
227                        unsigned int dim, expr_t *size_is, expr_t *length_is,
228                        unsigned char ptr_default_fc)
229 {
230     type_t *t = make_type(TYPE_ARRAY);
231     if (name) t->name = xstrdup(name);
232     t->details.array.declptr = declptr;
233     t->details.array.length_is = length_is;
234     if (size_is)
235         t->details.array.size_is = size_is;
236     else
237         t->details.array.dim = dim;
238     t->details.array.elem = element;
239     t->details.array.ptr_def_fc = ptr_default_fc;
240     return t;
241 }
242 
243 type_t *type_new_basic(enum type_basic_type basic_type)
244 {
245     type_t *t = make_type(TYPE_BASIC);
246     t->details.basic.type = basic_type;
247     t->details.basic.sign = 0;
248     return t;
249 }
250 
251 type_t *type_new_int(enum type_basic_type basic_type, int sign)
252 {
253     static type_t *int_types[TYPE_BASIC_INT_MAX+1][3];
254 
255     assert(basic_type <= TYPE_BASIC_INT_MAX);
256 
257     /* map sign { -1, 0, 1 } -> { 0, 1, 2 } */
258     if (!int_types[basic_type][sign + 1])
259     {
260         int_types[basic_type][sign + 1] = type_new_basic(basic_type);
261         int_types[basic_type][sign + 1]->details.basic.sign = sign;
262     }
263     return int_types[basic_type][sign + 1];
264 }
265 
266 type_t *type_new_void(void)
267 {
268     static type_t *void_type = NULL;
269     if (!void_type)
270         void_type = make_type(TYPE_VOID);
271     return void_type;
272 }
273 
274 type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
275 {
276     type_t *tag_type = name ? find_type(name, namespace, tsENUM) : NULL;
277     type_t *t = make_type(TYPE_ENUM);
278     t->name = name;
279     t->namespace = namespace;
280 
281     if (tag_type && tag_type->details.enumeration)
282         t->details.enumeration = tag_type->details.enumeration;
283     else if (defined)
284     {
285         t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
286         t->details.enumeration->enums = enums;
287         t->defined = TRUE;
288     }
289 
290     if (name)
291     {
292         if (defined)
293             reg_type(t, name, namespace, tsENUM);
294         else
295             add_incomplete(t);
296     }
297     return t;
298 }
299 
300 type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields)
301 {
302     type_t *tag_type = name ? find_type(name, namespace, tsSTRUCT) : NULL;
303     type_t *t;
304 
305     /* avoid creating duplicate typelib type entries */
306     if (tag_type && do_typelib) return tag_type;
307 
308     t = make_type(TYPE_STRUCT);
309     t->name = name;
310     t->namespace = namespace;
311 
312     if (tag_type && tag_type->details.structure)
313         t->details.structure = tag_type->details.structure;
314     else if (defined)
315     {
316         t->details.structure = xmalloc(sizeof(*t->details.structure));
317         t->details.structure->fields = fields;
318         t->defined = TRUE;
319     }
320     if (name)
321     {
322         if (defined)
323             reg_type(t, name, namespace, tsSTRUCT);
324         else
325             add_incomplete(t);
326     }
327     return t;
328 }
329 
330 type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
331 {
332     type_t *tag_type = name ? find_type(name, NULL, tsUNION) : NULL;
333     type_t *t = make_type(TYPE_UNION);
334     t->name = name;
335     if (tag_type && tag_type->details.structure)
336         t->details.structure = tag_type->details.structure;
337     else if (defined)
338     {
339         t->details.structure = xmalloc(sizeof(*t->details.structure));
340         t->details.structure->fields = fields;
341         t->defined = TRUE;
342     }
343     if (name)
344     {
345         if (defined)
346             reg_type(t, name, NULL, tsUNION);
347         else
348             add_incomplete(t);
349     }
350     return t;
351 }
352 
353 type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases)
354 {
355     type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, NULL, tsUNION);
356     if (!union_field) union_field = make_var( xstrdup("tagged_union") );
357     union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases);
358     t->details.structure = xmalloc(sizeof(*t->details.structure));
359     t->details.structure->fields = append_var( NULL, switch_field );
360     t->details.structure->fields = append_var( t->details.structure->fields, union_field );
361     t->defined = TRUE;
362     return t;
363 }
364 
365 static int is_valid_bitfield_type(const type_t *type)
366 {
367     switch (type_get_type(type))
368     {
369     case TYPE_ENUM:
370         return TRUE;
371     case TYPE_BASIC:
372         switch (type_basic_get_type(type))
373         {
374         case TYPE_BASIC_INT8:
375         case TYPE_BASIC_INT16:
376         case TYPE_BASIC_INT32:
377         case TYPE_BASIC_INT64:
378         case TYPE_BASIC_INT:
379         case TYPE_BASIC_INT3264:
380         case TYPE_BASIC_LONG:
381         case TYPE_BASIC_CHAR:
382         case TYPE_BASIC_HYPER:
383         case TYPE_BASIC_BYTE:
384         case TYPE_BASIC_WCHAR:
385         case TYPE_BASIC_ERROR_STATUS_T:
386             return TRUE;
387         case TYPE_BASIC_FLOAT:
388         case TYPE_BASIC_DOUBLE:
389         case TYPE_BASIC_HANDLE:
390             return FALSE;
391         }
392         return FALSE;
393     default:
394         return FALSE;
395     }
396 }
397 
398 type_t *type_new_bitfield(type_t *field, const expr_t *bits)
399 {
400     type_t *t;
401 
402     if (!is_valid_bitfield_type(field))
403         error_loc("bit-field has invalid type\n");
404 
405     if (bits->cval < 0)
406         error_loc("negative width for bit-field\n");
407 
408     /* FIXME: validate bits->cval <= memsize(field) * 8 */
409 
410     t = make_type(TYPE_BITFIELD);
411     t->details.bitfield.field = field;
412     t->details.bitfield.bits = bits;
413     return t;
414 }
415 
416 static int compute_method_indexes(type_t *iface)
417 {
418     int idx;
419     statement_t *stmt;
420 
421     if (!iface->details.iface)
422         return 0;
423 
424     if (type_iface_get_inherit(iface))
425         idx = compute_method_indexes(type_iface_get_inherit(iface));
426     else
427         idx = 0;
428 
429     STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
430     {
431         var_t *func = stmt->u.var;
432         if (!is_callas(func->attrs))
433             func->type->details.function->idx = idx++;
434     }
435 
436     return idx;
437 }
438 
439 void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
440 {
441     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
442     iface->details.iface->disp_props = NULL;
443     iface->details.iface->disp_methods = NULL;
444     iface->details.iface->stmts = stmts;
445     iface->details.iface->inherit = inherit;
446     iface->details.iface->disp_inherit = NULL;
447     iface->details.iface->async_iface = NULL;
448     iface->defined = TRUE;
449     compute_method_indexes(iface);
450 }
451 
452 void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
453 {
454     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
455     iface->details.iface->disp_props = props;
456     iface->details.iface->disp_methods = methods;
457     iface->details.iface->stmts = NULL;
458     iface->details.iface->inherit = find_type("IDispatch", NULL, 0);
459     if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n");
460     iface->details.iface->disp_inherit = NULL;
461     iface->details.iface->async_iface = NULL;
462     iface->defined = TRUE;
463     compute_method_indexes(iface);
464 }
465 
466 void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
467 {
468     dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
469     dispiface->details.iface->disp_props = NULL;
470     dispiface->details.iface->disp_methods = NULL;
471     dispiface->details.iface->stmts = NULL;
472     dispiface->details.iface->inherit = find_type("IDispatch", NULL, 0);
473     if (!dispiface->details.iface->inherit) error_loc("IDispatch is undefined\n");
474     dispiface->details.iface->disp_inherit = iface;
475     dispiface->details.iface->async_iface = NULL;
476     dispiface->defined = TRUE;
477     compute_method_indexes(dispiface);
478 }
479 
480 void type_module_define(type_t *module, statement_list_t *stmts)
481 {
482     if (module->details.module) error_loc("multiple definition error\n");
483     module->details.module = xmalloc(sizeof(*module->details.module));
484     module->details.module->stmts = stmts;
485     module->defined = TRUE;
486 }
487 
488 type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
489 {
490     coclass->details.coclass.ifaces = ifaces;
491     coclass->defined = TRUE;
492     return coclass;
493 }
494 
495 int type_is_equal(const type_t *type1, const type_t *type2)
496 {
497     if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
498         return FALSE;
499 
500     if (type1->name && type2->name)
501         return !strcmp(type1->name, type2->name);
502     else if ((!type1->name && type2->name) || (type1->name && !type2->name))
503         return FALSE;
504 
505     /* FIXME: do deep inspection of types to determine if they are equal */
506 
507     return FALSE;
508 }
509