2 * Copyright 2002 Ove Kaaven
3 * Copyright 2006-2008 Robert Shearman
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.
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.
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
25 #include "parser.tab.h"
27 attr_t
*attr_int( struct location where
, enum attr_type attr_type
, unsigned int val
)
29 attr_t
*a
= xmalloc( sizeof(attr_t
) );
36 attr_t
*attr_ptr( struct location where
, enum attr_type attr_type
, void *val
)
38 attr_t
*a
= xmalloc( sizeof(attr_t
) );
45 int is_attr( const attr_list_t
*list
, enum attr_type attr_type
)
49 LIST_FOR_EACH_ENTRY( attr
, list
, const attr_t
, entry
)
50 if (attr
->type
== attr_type
) return 1;
54 int is_ptrchain_attr( const var_t
*var
, enum attr_type attr_type
)
56 type_t
*type
= var
->declspec
.type
;
57 if (is_attr( var
->attrs
, attr_type
)) return 1;
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
);
67 int is_aliaschain_attr( const type_t
*type
, enum attr_type attr_type
)
69 const type_t
*t
= type
;
72 if (is_attr( t
->attrs
, attr_type
)) return 1;
73 else if (type_is_alias( t
)) t
= type_alias_get_aliasee_type( t
);
78 unsigned int get_attrv( const attr_list_t
*list
, enum attr_type attr_type
)
82 LIST_FOR_EACH_ENTRY( attr
, list
, const attr_t
, entry
)
83 if (attr
->type
== attr_type
) return attr
->u
.ival
;
87 void *get_attrp( const attr_list_t
*list
, enum attr_type attr_type
)
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
;
96 void *get_aliaschain_attrp( const type_t
*type
, enum attr_type attr_type
)
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
);
108 unsigned int dce_compatible
: 1;
109 unsigned int acf
: 1;
110 unsigned int multiple
: 1;
112 unsigned int on_interface
: 1;
113 unsigned int on_function
: 1;
114 unsigned int on_arg
: 1;
115 unsigned int on_type
: 1;
116 unsigned int on_enum
: 1;
117 unsigned int on_enum_member
: 1;
118 unsigned int on_struct
: 2;
119 unsigned int on_union
: 1;
120 unsigned int on_field
: 1;
121 unsigned int on_library
: 1;
122 unsigned int on_dispinterface
: 1;
123 unsigned int on_module
: 1;
124 unsigned int on_coclass
: 1;
125 unsigned int on_apicontract
: 1;
126 unsigned int on_runtimeclass
: 1;
127 const char *display_name
;
130 struct allowed_attr allowed_attr
[] =
132 /* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
133 /* ATTR_ACTIVATABLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "activatable" },
134 /* ATTR_AGGREGATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "aggregatable" },
135 /* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
136 /* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
137 /* ATTR_APPOBJECT */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "appobject" },
138 /* ATTR_ASYNC */ { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
139 /* ATTR_ASYNCUUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "async_uuid" },
140 /* ATTR_AUTO_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
141 /* ATTR_BINDABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
142 /* ATTR_BROADCAST */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
143 /* ATTR_CALLAS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
144 /* ATTR_CALLCONV */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL
},
145 /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "case" },
146 /* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
147 /* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
148 /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
149 /* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, "contract" },
150 /* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "contractversion" },
151 /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, "control" },
152 /* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, "custom" },
153 /* ATTR_DECODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
154 /* ATTR_DEFAULT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "default" },
155 /* ATTR_DEFAULTBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
156 /* ATTR_DEFAULTCOLLELEM */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
157 /* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
158 /* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" },
159 /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
160 /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL
},
161 /* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
162 /* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "dllname" },
163 /* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
164 /* ATTR_ENABLEALLOCATE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
165 /* ATTR_ENCODE */ { 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
166 /* ATTR_ENDPOINT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
167 /* ATTR_ENTRY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
168 /* ATTR_EVENTADD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventadd" },
169 /* ATTR_EVENTREMOVE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "eventremove" },
170 /* ATTR_EXCLUSIVETO */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "exclusive_to" },
171 /* ATTR_EXPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
172 /* ATTR_FAULTSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
173 /* ATTR_FLAGS */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "flags" },
174 /* ATTR_FORCEALLOCATE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
175 /* ATTR_HANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
176 /* ATTR_HELPCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpcontext" },
177 /* ATTR_HELPFILE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpfile" },
178 /* ATTR_HELPSTRING */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstring" },
179 /* ATTR_HELPSTRINGCONTEXT */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, "helpstringcontext" },
180 /* ATTR_HELPSTRINGDLL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "helpstringdll" },
181 /* ATTR_HIDDEN */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, "hidden" },
182 /* ATTR_ID */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, "id" },
183 /* ATTR_IDEMPOTENT */ { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
184 /* ATTR_IGNORE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ignore" },
185 /* ATTR_IIDIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "iid_is" },
186 /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
187 /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
188 /* ATTR_IN */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
189 /* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
190 /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "length_is" },
191 /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "lcid" },
192 /* ATTR_LICENSED */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "licensed" },
193 /* ATTR_LOCAL */ { 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
194 /* ATTR_MARSHALING_BEHAVIOR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "marshaling_behavior" },
195 /* ATTR_MAYBE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
196 /* ATTR_MESSAGE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
197 /* ATTR_NOCODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
198 /* ATTR_NONBROWSABLE */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
199 /* ATTR_NONCREATABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "noncreatable" },
200 /* ATTR_NONEXTENSIBLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
201 /* ATTR_NOTIFY */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
202 /* ATTR_NOTIFYFLAG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
203 /* ATTR_OBJECT */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
204 /* ATTR_ODL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "odl" },
205 /* ATTR_OLEAUTOMATION */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
206 /* ATTR_OPTIMIZE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
207 /* ATTR_OPTIONAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
208 /* ATTR_OUT */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
209 /* ATTR_OVERLOAD */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "overload" },
210 /* ATTR_PARAMLCID */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
211 /* ATTR_PARTIALIGNORE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
212 /* ATTR_POINTERDEFAULT */ { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
213 /* ATTR_POINTERTYPE */ { 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "ref, unique or ptr" },
214 /* ATTR_PROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "progid" },
215 /* ATTR_PROPGET */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
216 /* ATTR_PROPPUT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
217 /* ATTR_PROPPUTREF */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
218 /* ATTR_PROXY */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
219 /* ATTR_PUBLIC */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
220 /* ATTR_RANGE */ { 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "range" },
221 /* ATTR_READONLY */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "readonly" },
222 /* ATTR_REPRESENTAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
223 /* ATTR_REQUESTEDIT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
224 /* ATTR_RESTRICTED */ { 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, "restricted" },
225 /* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
226 /* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
227 /* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
228 /* ATTR_STATIC */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "static" },
229 /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
230 /* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
231 /* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
232 /* ATTR_SWITCHTYPE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_type" },
233 /* ATTR_THREADING */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, "threading" },
234 /* ATTR_TRANSMITAS */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
235 /* ATTR_UIDEFAULT */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
236 /* ATTR_USESGETLASTERROR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
237 /* ATTR_USERMARSHAL */ { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
238 /* ATTR_UUID */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, "uuid" },
239 /* ATTR_V1ENUM */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
240 /* ATTR_VARARG */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
241 /* ATTR_VERSION */ { 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 1, 1, 0, 1, "version" },
242 /* ATTR_VIPROGID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "vi_progid" },
243 /* ATTR_WIREMARSHAL */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
246 static const char *get_attr_display_name( enum attr_type attr_type
)
248 return allowed_attr
[attr_type
].display_name
;
251 attr_list_t
*append_attr( attr_list_t
*list
, attr_t
*attr
)
253 attr_t
*attr_existing
;
254 if (!attr
) return list
;
257 list
= xmalloc( sizeof(*list
) );
260 if (!allowed_attr
[attr
->type
].multiple
)
262 LIST_FOR_EACH_ENTRY( attr_existing
, list
, attr_t
, entry
)
264 if (attr_existing
->type
!= attr
->type
) continue;
265 warning_at( &attr
->where
, "duplicate attribute %s\n", get_attr_display_name( attr
->type
) );
266 /* use the last attribute, like MIDL does */
267 list_remove( &attr_existing
->entry
);
271 list_add_tail( list
, &attr
->entry
);
275 attr_list_t
*append_attr_list( attr_list_t
*new_list
, attr_list_t
*old_list
)
279 if (!old_list
) return new_list
;
281 while ((entry
= list_head( old_list
)))
283 attr_t
*attr
= LIST_ENTRY( entry
, attr_t
, entry
);
284 list_remove( entry
);
285 new_list
= append_attr( new_list
, attr
);
290 attr_list_t
*append_attribs( attr_list_t
*l1
, attr_list_t
*l2
)
293 if (!l1
|| l1
== l2
) return l2
;
294 list_move_tail( l1
, l2
);
298 attr_list_t
*map_attrs( const attr_list_t
*list
, map_attrs_filter_t filter
)
300 attr_list_t
*new_list
;
304 if (!list
) return NULL
;
306 new_list
= xmalloc( sizeof(*list
) );
307 list_init( new_list
);
308 LIST_FOR_EACH_ENTRY( attr
, list
, const attr_t
, entry
)
310 if (filter
&& !filter( new_list
, attr
)) continue;
311 new_attr
= xmalloc( sizeof(*new_attr
) );
313 list_add_tail( new_list
, &new_attr
->entry
);
318 attr_list_t
*move_attr( attr_list_t
*dst
, attr_list_t
*src
, enum attr_type type
)
321 if (!src
) return dst
;
322 LIST_FOR_EACH_ENTRY( attr
, src
, attr_t
, entry
)
324 if (attr
->type
== type
)
326 list_remove( &attr
->entry
);
327 return append_attr( dst
, attr
);
333 attr_list_t
*check_apicontract_attrs( const char *name
, attr_list_t
*attrs
)
336 if (!attrs
) return NULL
;
337 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
339 if (!allowed_attr
[attr
->type
].on_apicontract
)
340 error_at( &attr
->where
, "inapplicable attribute %s for apicontract %s\n",
341 allowed_attr
[attr
->type
].display_name
, name
);
346 attr_list_t
*check_coclass_attrs( const char *name
, attr_list_t
*attrs
)
349 if (!attrs
) return NULL
;
350 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
352 if (!allowed_attr
[attr
->type
].on_coclass
)
353 error_at( &attr
->where
, "inapplicable attribute %s for coclass %s\n",
354 allowed_attr
[attr
->type
].display_name
, name
);
359 attr_list_t
*check_dispiface_attrs( const char *name
, attr_list_t
*attrs
)
362 if (!attrs
) return NULL
;
363 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
365 if (!allowed_attr
[attr
->type
].on_dispinterface
)
366 error_at( &attr
->where
, "inapplicable attribute %s for dispinterface %s\n",
367 allowed_attr
[attr
->type
].display_name
, name
);
372 attr_list_t
*check_enum_attrs( attr_list_t
*attrs
)
375 if (!attrs
) return NULL
;
376 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
378 if (!allowed_attr
[attr
->type
].on_enum
)
379 error_at( &attr
->where
, "inapplicable attribute %s for enum\n",
380 allowed_attr
[attr
->type
].display_name
);
385 attr_list_t
*check_enum_member_attrs( attr_list_t
*attrs
)
388 if (!attrs
) return NULL
;
389 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
391 if (!allowed_attr
[attr
->type
].on_enum_member
)
392 error_at( &attr
->where
, "inapplicable attribute %s for enum member\n",
393 allowed_attr
[attr
->type
].display_name
);
398 attr_list_t
*check_field_attrs( const char *name
, attr_list_t
*attrs
)
401 if (!attrs
) return NULL
;
402 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
404 if (!allowed_attr
[attr
->type
].on_field
)
405 error_at( &attr
->where
, "inapplicable attribute %s for field %s\n",
406 allowed_attr
[attr
->type
].display_name
, name
);
411 attr_list_t
*check_function_attrs( const char *name
, attr_list_t
*attrs
)
414 if (!attrs
) return NULL
;
415 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
417 if (!allowed_attr
[attr
->type
].on_function
)
418 error_at( &attr
->where
, "inapplicable attribute %s for function %s\n",
419 allowed_attr
[attr
->type
].display_name
, name
);
424 attr_list_t
*check_interface_attrs( const char *name
, attr_list_t
*attrs
)
427 if (!attrs
) return NULL
;
428 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
430 if (!allowed_attr
[attr
->type
].on_interface
)
431 error_at( &attr
->where
, "inapplicable attribute %s for interface %s\n",
432 allowed_attr
[attr
->type
].display_name
, name
);
433 if (attr
->type
== ATTR_IMPLICIT_HANDLE
)
435 const var_t
*var
= attr
->u
.pval
;
436 if (type_get_type( var
->declspec
.type
) == TYPE_BASIC
&&
437 type_basic_get_type( var
->declspec
.type
) == TYPE_BASIC_HANDLE
)
439 if (is_aliaschain_attr( var
->declspec
.type
, ATTR_HANDLE
)) continue;
440 error_at( &attr
->where
, "attribute %s requires a handle type in interface %s\n",
441 allowed_attr
[attr
->type
].display_name
, name
);
447 attr_list_t
*check_library_attrs( const char *name
, attr_list_t
*attrs
)
450 if (!attrs
) return NULL
;
451 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
453 if (!allowed_attr
[attr
->type
].on_library
)
454 error_at( &attr
->where
, "inapplicable attribute %s for library %s\n",
455 allowed_attr
[attr
->type
].display_name
, name
);
460 attr_list_t
*check_module_attrs( const char *name
, attr_list_t
*attrs
)
463 if (!attrs
) return NULL
;
464 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
466 if (!allowed_attr
[attr
->type
].on_module
)
467 error_at( &attr
->where
, "inapplicable attribute %s for module %s\n",
468 allowed_attr
[attr
->type
].display_name
, name
);
473 attr_list_t
*check_runtimeclass_attrs( const char *name
, attr_list_t
*attrs
)
476 if (!attrs
) return NULL
;
477 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
479 if (!allowed_attr
[attr
->type
].on_runtimeclass
)
480 error_at( &attr
->where
, "inapplicable attribute %s for runtimeclass %s\n",
481 allowed_attr
[attr
->type
].display_name
, name
);
486 attr_list_t
*check_struct_attrs( attr_list_t
*attrs
)
488 int mask
= winrt_mode
? 3 : 1;
490 if (!attrs
) return NULL
;
491 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
493 if (!(allowed_attr
[attr
->type
].on_struct
& mask
))
494 error_at( &attr
->where
, "inapplicable attribute %s for struct\n",
495 allowed_attr
[attr
->type
].display_name
);
500 attr_list_t
*check_typedef_attrs( attr_list_t
*attrs
)
503 if (!attrs
) return NULL
;
504 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
506 if (!allowed_attr
[attr
->type
].on_type
)
507 error_at( &attr
->where
, "inapplicable attribute %s for typedef\n",
508 allowed_attr
[attr
->type
].display_name
);
513 attr_list_t
*check_union_attrs( attr_list_t
*attrs
)
516 if (!attrs
) return NULL
;
517 LIST_FOR_EACH_ENTRY( attr
, attrs
, const attr_t
, entry
)
519 if (!allowed_attr
[attr
->type
].on_union
)
520 error_at( &attr
->where
, "inapplicable attribute %s for union\n",
521 allowed_attr
[attr
->type
].display_name
);
526 void check_arg_attrs( const var_t
*arg
)
529 if (!arg
->attrs
) return;
530 LIST_FOR_EACH_ENTRY( attr
, arg
->attrs
, const attr_t
, entry
)
532 if (!allowed_attr
[attr
->type
].on_arg
)
533 error_at( &attr
->where
, "inapplicable attribute %s for argument %s\n",
534 allowed_attr
[attr
->type
].display_name
, arg
->name
);