widl: Add a new function, type_iface_get_inherit.
[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 static int compute_method_indexes(type_t *iface)
82 {
83     int idx;
84     statement_t *stmt;
85
86     if (!iface->details.iface)
87         return 0;
88
89     if (type_iface_get_inherit(iface))
90         idx = compute_method_indexes(type_iface_get_inherit(iface));
91     else
92         idx = 0;
93
94     STATEMENTS_FOR_EACH_FUNC( stmt, iface->details.iface->stmts )
95     {
96         var_t *func = stmt->u.var;
97         if (!is_callas(func->attrs))
98             func->type->details.function->idx = idx++;
99     }
100
101     return idx;
102 }
103
104 void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
105 {
106     iface->ref = inherit;
107     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
108     iface->details.iface->disp_props = NULL;
109     iface->details.iface->disp_methods = NULL;
110     iface->details.iface->stmts = stmts;
111     iface->defined = TRUE;
112     compute_method_indexes(iface);
113 }
114
115 void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods)
116 {
117     iface->ref = find_type("IDispatch", 0);
118     if (!iface->ref) error_loc("IDispatch is undefined\n");
119     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
120     iface->details.iface->disp_props = props;
121     iface->details.iface->disp_methods = methods;
122     iface->details.iface->stmts = NULL;
123     iface->defined = TRUE;
124     compute_method_indexes(iface);
125 }
126
127 void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
128 {
129     type_dispinterface_define(dispiface, iface->details.iface->disp_props,
130                               iface->details.iface->disp_methods);
131 }
132
133 void type_module_define(type_t *module, statement_list_t *stmts)
134 {
135     if (module->details.module) error_loc("multiple definition error\n");
136     module->details.module = xmalloc(sizeof(*module->details.module));
137     module->details.module->stmts = stmts;
138     module->defined = TRUE;
139 }
140
141 type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
142 {
143     coclass->details.coclass.ifaces = ifaces;
144     coclass->defined = TRUE;
145     return coclass;
146 }