Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/tools/widl/attribute.c
4389 views
1
/*
2
* Copyright 2002 Ove Kaaven
3
* Copyright 2006-2008 Robert Shearman
4
*
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
9
*
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18
*/
19
20
#include "config.h"
21
22
#include "widl.h"
23
#include "typetree.h"
24
25
#include "parser.tab.h"
26
27
attr_t *attr_int( struct location where, enum attr_type attr_type, unsigned int val )
28
{
29
attr_t *a = xmalloc( sizeof(attr_t) );
30
a->where = where;
31
a->type = attr_type;
32
a->u.ival = val;
33
return a;
34
}
35
36
attr_t *attr_ptr( struct location where, enum attr_type attr_type, void *val )
37
{
38
attr_t *a = xmalloc( sizeof(attr_t) );
39
a->where = where;
40
a->type = attr_type;
41
a->u.pval = val;
42
return a;
43
}
44
45
int is_attr( const attr_list_t *list, enum attr_type attr_type )
46
{
47
const attr_t *attr;
48
if (!list) return 0;
49
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
50
if (attr->type == attr_type) return 1;
51
return 0;
52
}
53
54
int is_ptrchain_attr( const var_t *var, enum attr_type attr_type )
55
{
56
type_t *type = var->declspec.type;
57
if (is_attr( var->attrs, attr_type )) return 1;
58
for (;;)
59
{
60
if (is_attr( type->attrs, attr_type )) return 1;
61
else if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
62
else if (type_is_ptr( type )) type = type_pointer_get_ref_type( type );
63
else return 0;
64
}
65
}
66
67
int is_aliaschain_attr( const type_t *type, enum attr_type attr_type )
68
{
69
const type_t *t = type;
70
for (;;)
71
{
72
if (is_attr( t->attrs, attr_type )) return 1;
73
else if (type_is_alias( t )) t = type_alias_get_aliasee_type( t );
74
else return 0;
75
}
76
}
77
78
unsigned int get_attrv( const attr_list_t *list, enum attr_type attr_type )
79
{
80
const attr_t *attr;
81
if (!list) return 0;
82
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
83
if (attr->type == attr_type) return attr->u.ival;
84
return 0;
85
}
86
87
void *get_attrp( const attr_list_t *list, enum attr_type attr_type )
88
{
89
const attr_t *attr;
90
if (!list) return NULL;
91
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
92
if (attr->type == attr_type) return attr->u.pval;
93
return NULL;
94
}
95
96
void *get_aliaschain_attrp( const type_t *type, enum attr_type attr_type )
97
{
98
for (;;)
99
{
100
if (is_attr( type->attrs, attr_type )) return get_attrp( type->attrs, attr_type );
101
if (!type_is_alias( type )) return NULL;
102
type = type_alias_get_aliasee_type( type );
103
}
104
}
105
106
void get_version( const attr_list_t *list, unsigned short *major, unsigned short *minor )
107
{
108
version_t *version = get_attrp( list, ATTR_VERSION );
109
if (version)
110
{
111
*major = version->major;
112
*minor = version->minor;
113
}
114
else *major = *minor = 0;
115
}
116
117
struct allowed_attr
118
{
119
unsigned int dce_compatible : 1;
120
unsigned int acf : 1;
121
unsigned int multiple : 1;
122
123
unsigned int on_interface : 1;
124
unsigned int on_function : 1;
125
unsigned int on_arg : 1;
126
unsigned int on_type : 1;
127
unsigned int on_enum : 1;
128
unsigned int on_enum_member : 1;
129
unsigned int on_struct : 2;
130
unsigned int on_union : 1;
131
unsigned int on_field : 1;
132
unsigned int on_library : 1;
133
unsigned int on_dispinterface : 1;
134
unsigned int on_module : 1;
135
unsigned int on_coclass : 1;
136
unsigned int on_apicontract : 1;
137
unsigned int on_runtimeclass : 1;
138
const char *display_name;
139
};
140
141
struct allowed_attr allowed_attr[] =
142
{
143
/* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
144
/* ATTR_ACTIVATABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "activatable" },
145
/* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
146
/* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
147
/* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
148
/* ATTR_APICONTACT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "apicontract" },
149
/* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "appobject" },
150
/* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
151
/* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "async_uuid" },
152
/* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
153
/* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
154
/* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
155
/* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
156
/* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
157
/* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "case" },
158
/* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
159
/* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
160
/* ATTR_COMPOSABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "composable" },
161
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
162
/* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" },
163
/* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" },
164
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" },
165
/* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, "custom" },
166
/* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
167
/* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "default" },
168
/* ATTR_DEFAULT_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "default_overload" },
169
/* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
170
/* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
171
/* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
172
/* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" },
173
/* ATTR_DEPRECATED */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "deprecated" },
174
/* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
175
/* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL },
176
/* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
177
/* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "dllname" },
178
/* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
179
/* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
180
/* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
181
/* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
182
/* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
183
/* ATTR_EVENTADD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
184
/* ATTR_EVENTREMOVE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
185
/* ATTR_EXCLUSIVETO */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
186
/* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
187
/* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
188
/* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
189
/* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
190
/* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
191
/* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
192
/* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" },
193
/* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" },
194
/* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" },
195
/* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" },
196
/* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, "hidden" },
197
/* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" },
198
/* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
199
/* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ignore" },
200
/* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "iid_is" },
201
/* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
202
/* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
203
/* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
204
/* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
205
/* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "length_is" },
206
/* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" },
207
/* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" },
208
/* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
209
/* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" },
210
/* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
211
/* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
212
/* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
213
/* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
214
/* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "noncreatable" },
215
/* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
216
/* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
217
/* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
218
/* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
219
/* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" },
220
/* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
221
/* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
222
/* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
223
/* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
224
/* ATTR_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "overload" },
225
/* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
226
/* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
227
/* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
228
/* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ref, unique or ptr" },
229
/* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "progid" },
230
/* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
231
/* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
232
/* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
233
/* ATTR_PROTECTED */ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "protected" },
234
/* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
235
/* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
236
/* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" },
237
/* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" },
238
/* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
239
/* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
240
/* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" },
241
/* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
242
/* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
243
/* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
244
/* ATTR_STATIC */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "static" },
245
/* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
246
/* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
247
/* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
248
/* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_type" },
249
/* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" },
250
/* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
251
/* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
252
/* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
253
/* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
254
/* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" },
255
/* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
256
/* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
257
/* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 1, 1, 0, 1, "version" },
258
/* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" },
259
/* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
260
};
261
262
static const char *get_attr_display_name( enum attr_type attr_type )
263
{
264
return allowed_attr[attr_type].display_name;
265
}
266
267
attr_list_t *append_attr( attr_list_t *list, attr_t *attr )
268
{
269
attr_t *attr_existing;
270
if (!attr) return list;
271
if (!list)
272
{
273
list = xmalloc( sizeof(*list) );
274
list_init( list );
275
}
276
if (!allowed_attr[attr->type].multiple)
277
{
278
LIST_FOR_EACH_ENTRY( attr_existing, list, attr_t, entry )
279
{
280
if (attr_existing->type != attr->type) continue;
281
warning_at( &attr->where, "duplicate attribute %s\n", get_attr_display_name( attr->type ) );
282
/* use the last attribute, like MIDL does */
283
list_remove( &attr_existing->entry );
284
break;
285
}
286
}
287
list_add_tail( list, &attr->entry );
288
return list;
289
}
290
291
attr_list_t *append_attr_list( attr_list_t *new_list, attr_list_t *old_list )
292
{
293
struct list *entry;
294
295
if (!old_list) return new_list;
296
297
while ((entry = list_head( old_list )))
298
{
299
attr_t *attr = LIST_ENTRY( entry, attr_t, entry );
300
list_remove( entry );
301
new_list = append_attr( new_list, attr );
302
}
303
return new_list;
304
}
305
306
attr_list_t *append_attribs( attr_list_t *l1, attr_list_t *l2 )
307
{
308
if (!l2) return l1;
309
if (!l1 || l1 == l2) return l2;
310
list_move_tail( l1, l2 );
311
return l1;
312
}
313
314
attr_list_t *map_attrs( const attr_list_t *list, map_attrs_filter_t filter )
315
{
316
attr_list_t *new_list;
317
const attr_t *attr;
318
attr_t *new_attr;
319
320
if (!list) return NULL;
321
322
new_list = xmalloc( sizeof(*list) );
323
list_init( new_list );
324
LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry )
325
{
326
if (filter && !filter( new_list, attr )) continue;
327
new_attr = xmalloc( sizeof(*new_attr) );
328
*new_attr = *attr;
329
list_add_tail( new_list, &new_attr->entry );
330
}
331
return new_list;
332
}
333
334
attr_list_t *move_attr( attr_list_t *dst, attr_list_t *src, enum attr_type type )
335
{
336
attr_t *attr;
337
if (!src) return dst;
338
LIST_FOR_EACH_ENTRY( attr, src, attr_t, entry )
339
{
340
if (attr->type == type)
341
{
342
list_remove( &attr->entry );
343
return append_attr( dst, attr );
344
}
345
}
346
return dst;
347
}
348
349
attr_list_t *check_apicontract_attrs( const char *name, attr_list_t *attrs )
350
{
351
const attr_t *attr;
352
if (!attrs) return NULL;
353
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
354
{
355
if (!allowed_attr[attr->type].on_apicontract)
356
error_at( &attr->where, "inapplicable attribute %s for apicontract %s\n",
357
allowed_attr[attr->type].display_name, name );
358
}
359
return attrs;
360
}
361
362
attr_list_t *check_coclass_attrs( const char *name, attr_list_t *attrs )
363
{
364
const attr_t *attr;
365
if (!attrs) return NULL;
366
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
367
{
368
if (!allowed_attr[attr->type].on_coclass)
369
error_at( &attr->where, "inapplicable attribute %s for coclass %s\n",
370
allowed_attr[attr->type].display_name, name );
371
}
372
return attrs;
373
}
374
375
attr_list_t *check_dispiface_attrs( const char *name, attr_list_t *attrs )
376
{
377
const attr_t *attr;
378
if (!attrs) return NULL;
379
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
380
{
381
if (!allowed_attr[attr->type].on_dispinterface)
382
error_at( &attr->where, "inapplicable attribute %s for dispinterface %s\n",
383
allowed_attr[attr->type].display_name, name );
384
}
385
return attrs;
386
}
387
388
attr_list_t *check_enum_attrs( attr_list_t *attrs )
389
{
390
const attr_t *attr;
391
if (!attrs) return NULL;
392
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
393
{
394
if (!allowed_attr[attr->type].on_enum)
395
error_at( &attr->where, "inapplicable attribute %s for enum\n",
396
allowed_attr[attr->type].display_name );
397
}
398
return attrs;
399
}
400
401
attr_list_t *check_enum_member_attrs( attr_list_t *attrs )
402
{
403
const attr_t *attr;
404
if (!attrs) return NULL;
405
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
406
{
407
if (!allowed_attr[attr->type].on_enum_member)
408
error_at( &attr->where, "inapplicable attribute %s for enum member\n",
409
allowed_attr[attr->type].display_name );
410
}
411
return attrs;
412
}
413
414
attr_list_t *check_field_attrs( const char *name, attr_list_t *attrs )
415
{
416
const attr_t *attr;
417
if (!attrs) return NULL;
418
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
419
{
420
if (!allowed_attr[attr->type].on_field)
421
error_at( &attr->where, "inapplicable attribute %s for field %s\n",
422
allowed_attr[attr->type].display_name, name );
423
}
424
return attrs;
425
}
426
427
attr_list_t *check_function_attrs( const char *name, attr_list_t *attrs )
428
{
429
const attr_t *attr;
430
if (!attrs) return NULL;
431
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
432
{
433
if (!allowed_attr[attr->type].on_function)
434
error_at( &attr->where, "inapplicable attribute %s for function %s\n",
435
allowed_attr[attr->type].display_name, name );
436
}
437
return attrs;
438
}
439
440
attr_list_t *check_interface_attrs( const char *name, attr_list_t *attrs )
441
{
442
const attr_t *attr;
443
if (!attrs) return NULL;
444
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
445
{
446
if (!allowed_attr[attr->type].on_interface)
447
error_at( &attr->where, "inapplicable attribute %s for interface %s\n",
448
allowed_attr[attr->type].display_name, name );
449
if (attr->type == ATTR_IMPLICIT_HANDLE)
450
{
451
const var_t *var = attr->u.pval;
452
if (type_get_type( var->declspec.type ) == TYPE_BASIC &&
453
type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
454
continue;
455
if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE )) continue;
456
error_at( &attr->where, "attribute %s requires a handle type in interface %s\n",
457
allowed_attr[attr->type].display_name, name );
458
}
459
}
460
return attrs;
461
}
462
463
attr_list_t *check_library_attrs( const char *name, attr_list_t *attrs )
464
{
465
const attr_t *attr;
466
if (!attrs) return NULL;
467
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
468
{
469
if (!allowed_attr[attr->type].on_library)
470
error_at( &attr->where, "inapplicable attribute %s for library %s\n",
471
allowed_attr[attr->type].display_name, name );
472
}
473
return attrs;
474
}
475
476
attr_list_t *check_module_attrs( const char *name, attr_list_t *attrs )
477
{
478
const attr_t *attr;
479
if (!attrs) return NULL;
480
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
481
{
482
if (!allowed_attr[attr->type].on_module)
483
error_at( &attr->where, "inapplicable attribute %s for module %s\n",
484
allowed_attr[attr->type].display_name, name );
485
}
486
return attrs;
487
}
488
489
attr_list_t *check_runtimeclass_attrs( const char *name, attr_list_t *attrs )
490
{
491
const attr_t *attr;
492
bool found_version = false;
493
if (!attrs) return NULL;
494
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
495
{
496
if (!allowed_attr[attr->type].on_runtimeclass)
497
error_at( &attr->where, "inapplicable attribute %s for runtimeclass %s\n",
498
allowed_attr[attr->type].display_name, name );
499
if (attr->type == ATTR_CONTRACT || attr->type == ATTR_VERSION)
500
found_version = true;
501
}
502
if (!found_version)
503
error_at( NULL, "runtimeclass %s requires contract or version attribute\n", name );
504
return attrs;
505
}
506
507
attr_list_t *check_struct_attrs( attr_list_t *attrs )
508
{
509
int mask = winrt_mode ? 3 : 1;
510
const attr_t *attr;
511
if (!attrs) return NULL;
512
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
513
{
514
if (!(allowed_attr[attr->type].on_struct & mask))
515
error_at( &attr->where, "inapplicable attribute %s for struct\n",
516
allowed_attr[attr->type].display_name );
517
}
518
return attrs;
519
}
520
521
attr_list_t *check_typedef_attrs( attr_list_t *attrs )
522
{
523
const attr_t *attr;
524
if (!attrs) return NULL;
525
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
526
{
527
if (!allowed_attr[attr->type].on_type)
528
error_at( &attr->where, "inapplicable attribute %s for typedef\n",
529
allowed_attr[attr->type].display_name );
530
}
531
return attrs;
532
}
533
534
attr_list_t *check_union_attrs( attr_list_t *attrs )
535
{
536
const attr_t *attr;
537
if (!attrs) return NULL;
538
LIST_FOR_EACH_ENTRY( attr, attrs, const attr_t, entry )
539
{
540
if (!allowed_attr[attr->type].on_union)
541
error_at( &attr->where, "inapplicable attribute %s for union\n",
542
allowed_attr[attr->type].display_name );
543
}
544
return attrs;
545
}
546
547
void check_arg_attrs( const var_t *arg )
548
{
549
const attr_t *attr;
550
if (!arg->attrs) return;
551
LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry )
552
{
553
if (!allowed_attr[attr->type].on_arg)
554
error_at( &attr->where, "inapplicable attribute %s for argument %s\n",
555
allowed_attr[attr->type].display_name, arg->name );
556
}
557
}
558
559