widl: Fix typos in write_remoting_arg which caused ref pointers to unions to not...
[wine] / tools / widl / typetree.c
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
26 #include "widl.h"
27 #include "utils.h"
28 #include "parser.h"
29 #include "typetree.h"
30 #include "header.h"
31
32 type_t *duptype(type_t *t, int dupname)
33 {
34   type_t *d = alloc_type();
35
36   *d = *t;
37   if (dupname && t->name)
38     d->name = xstrdup(t->name);
39
40   return d;
41 }
42
43 type_t *type_new_function(var_list_t *args)
44 {
45     type_t *t = make_type(RPC_FC_FUNCTION, NULL);
46     t->details.function = xmalloc(sizeof(*t->details.function));
47     t->details.function->args = args;
48     t->details.function->idx = -1;
49     return t;
50 }
51
52 type_t *type_new_pointer(type_t *ref, attr_list_t *attrs)
53 {
54     type_t *t = make_type(pointer_default, ref);
55     t->attrs = attrs;
56     return t;
57 }
58
59 type_t *type_new_alias(type_t *t, const char *name)
60 {
61     type_t *a = duptype(t, 0);
62
63     a->name = xstrdup(name);
64     a->attrs = NULL;
65     a->declarray = FALSE;
66     a->orig = t;
67     a->is_alias = TRUE;
68     init_loc_info(&a->loc_info);
69
70     return a;
71 }
72
73 type_t *type_new_module(char *name)
74 {
75     type_t *type = make_type(RPC_FC_MODULE, NULL);
76     type->name = name;
77     /* FIXME: register type to detect multiple definitions */
78     return type;
79 }
80
81 type_t *type_new_array(const char *name, type_t *element, int declarray,
82                        unsigned int dim, expr_t *size_is, expr_t *length_is)
83 {
84     type_t *t = make_type(RPC_FC_LGFARRAY, element);
85     if (name) t->name = xstrdup(name);
86     t->declarray = declarray;
87     t->details.array.length_is = length_is;
88     if (size_is)
89         t->details.array.size_is = size_is;
90     else
91         t->details.array.dim = dim;
92     return t;
93 }
94
95 static int compute_method_indexes(type_t *iface)
96 {
97     int idx;
98     statement_t *stmt;
99
100     if (!iface->details.iface)
101         return 0;
102
103     if (type_iface_get_inherit(iface))
104         idx = compute_method_indexes(type_iface_get_inherit(iface));
105     else
106         idx = 0;
107
108     STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
109     {
110         var_t *func = stmt->u.var;
111         if (!is_callas(func->attrs))
112             func->type->details.function->idx = idx++;
113     }
114
115     return idx;
116 }
117
118 void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
119 {
120     iface->ref = inherit;
121     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
122     iface->details.iface->disp_props = NULL;
123     iface->details.iface->disp_methods = NULL;
124     iface->details.iface->stmts = stmts;
125     iface->defined = TRUE;
126     compute_method_indexes(iface);
127 }
128
129 void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods)
130 {
131     iface->ref = find_type("IDispatch", 0);
132     if (!iface->ref) error_loc("IDispatch is undefined\n");
133     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
134     iface->details.iface->disp_props = props;
135     iface->details.iface->disp_methods = methods;
136     iface->details.iface->stmts = NULL;
137     iface->defined = TRUE;
138     compute_method_indexes(iface);
139 }
140
141 void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
142 {
143     type_dispinterface_define(dispiface, iface->details.iface->disp_props,
144                               iface->details.iface->disp_methods);
145 }
146
147 void type_module_define(type_t *module, statement_list_t *stmts)
148 {
149     if (module->details.module) error_loc("multiple definition error\n");
150     module->details.module = xmalloc(sizeof(*module->details.module));
151     module->details.module->stmts = stmts;
152     module->defined = TRUE;
153 }
154
155 type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
156 {
157     coclass->details.coclass.ifaces = ifaces;
158     coclass->defined = TRUE;
159     return coclass;
160 }