xref: /reactos/sdk/tools/widl/parser.y (revision 8540ab04)
1 %{
2 /*
3  * IDL Compiler
4  *
5  * Copyright 2002 Ove Kaaven
6  * Copyright 2006-2008 Robert Shearman
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include "config.h"
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <stdarg.h>
28 #include <assert.h>
29 #include <ctype.h>
30 #include <string.h>
31 
32 #include "widl.h"
33 #include "utils.h"
34 #include "parser.h"
35 #include "header.h"
36 #include "typelib.h"
37 #include "typegen.h"
38 #include "expr.h"
39 #include "typetree.h"
40 
41 static unsigned char pointer_default = RPC_FC_UP;
42 
43 typedef struct list typelist_t;
44 struct typenode {
45   type_t *type;
46   struct list entry;
47 };
48 
49 struct _import_t
50 {
51   char *name;
52   int import_performed;
53 };
54 
55 typedef struct _decl_spec_t
56 {
57   type_t *type;
58   attr_list_t *attrs;
59   enum storage_class stgclass;
60 } decl_spec_t;
61 
62 typelist_t incomplete_types = LIST_INIT(incomplete_types);
63 
64 static void fix_incomplete(void);
65 static void fix_incomplete_types(type_t *complete_type);
66 
67 static str_list_t *append_str(str_list_t *list, char *str);
68 static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
69 static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
70 static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
71 static attr_t *make_attr(enum attr_type type);
72 static attr_t *make_attrv(enum attr_type type, unsigned int val);
73 static attr_t *make_attrp(enum attr_type type, void *val);
74 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
75 static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
76 static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top);
77 static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls);
78 static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
79 static ifref_t *make_ifref(type_t *iface);
80 static var_list_t *append_var_list(var_list_t *list, var_list_t *vars);
81 static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p);
82 static declarator_t *make_declarator(var_t *var);
83 static type_t *make_safearray(type_t *type);
84 static typelib_t *make_library(const char *name, const attr_list_t *attrs);
85 static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type);
86 static warning_list_t *append_warning(warning_list_t *, int);
87 
88 static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
89 static type_t *find_type_or_error(const char *name, int t);
90 static type_t *find_type_or_error2(char *name, int t);
91 
92 static var_t *reg_const(var_t *var);
93 
94 static void push_namespace(const char *name);
95 static void pop_namespace(const char *name);
96 
97 static char *gen_name(void);
98 static void check_arg_attrs(const var_t *arg);
99 static void check_statements(const statement_list_t *stmts, int is_inside_library);
100 static void check_all_user_types(const statement_list_t *stmts);
101 static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
102 static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
103 static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
104 static attr_list_t *check_enum_attrs(attr_list_t *attrs);
105 static attr_list_t *check_struct_attrs(attr_list_t *attrs);
106 static attr_list_t *check_union_attrs(attr_list_t *attrs);
107 static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
108 static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
109 static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
110 static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
111 static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
112 const char *get_attr_display_name(enum attr_type type);
113 static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
114 static void check_def(const type_t *t);
115 
116 static statement_t *make_statement(enum statement_type type);
117 static statement_t *make_statement_type_decl(type_t *type);
118 static statement_t *make_statement_reference(type_t *type);
119 static statement_t *make_statement_declaration(var_t *var);
120 static statement_t *make_statement_library(typelib_t *typelib);
121 static statement_t *make_statement_pragma(const char *str);
122 static statement_t *make_statement_cppquote(const char *str);
123 static statement_t *make_statement_importlib(const char *str);
124 static statement_t *make_statement_module(type_t *type);
125 static statement_t *make_statement_typedef(var_list_t *names);
126 static statement_t *make_statement_import(const char *str);
127 static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
128 static statement_list_t *append_statements(statement_list_t *, statement_list_t *);
129 static attr_list_t *append_attribs(attr_list_t *, attr_list_t *);
130 
131 static struct namespace global_namespace = {
132     NULL, NULL, LIST_INIT(global_namespace.entry), LIST_INIT(global_namespace.children)
133 };
134 
135 static struct namespace *current_namespace = &global_namespace;
136 
137 %}
138 %union {
139 	attr_t *attr;
140 	attr_list_t *attr_list;
141 	str_list_t *str_list;
142 	expr_t *expr;
143 	expr_list_t *expr_list;
144 	array_dims_t *array_dims;
145 	type_t *type;
146 	var_t *var;
147 	var_list_t *var_list;
148 	declarator_t *declarator;
149 	declarator_list_t *declarator_list;
150 	statement_t *statement;
151 	statement_list_t *stmt_list;
152 	warning_t *warning;
153 	warning_list_t *warning_list;
154 	ifref_t *ifref;
155 	ifref_list_t *ifref_list;
156 	char *str;
157 	UUID *uuid;
158 	unsigned int num;
159 	double dbl;
160 	interface_info_t ifinfo;
161 	typelib_t *typelib;
162 	struct _import_t *import;
163 	struct _decl_spec_t *declspec;
164 	enum storage_class stgclass;
165 }
166 
167 %token <str> aIDENTIFIER aPRAGMA
168 %token <str> aKNOWNTYPE
169 %token <num> aNUM aHEXNUM
170 %token <dbl> aDOUBLE
171 %token <str> aSTRING aWSTRING aSQSTRING
172 %token <uuid> aUUID
173 %token aEOF
174 %token SHL SHR
175 %token MEMBERPTR
176 %token EQUALITY INEQUALITY
177 %token GREATEREQUAL LESSEQUAL
178 %token LOGICALOR LOGICALAND
179 %token ELLIPSIS
180 %token tAGGREGATABLE tALLOCATE tANNOTATION tAPPOBJECT tASYNC tASYNCUUID
181 %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
182 %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
183 %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
184 %token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE
185 %token tDECODE tDEFAULT tDEFAULTBIND
186 %token tDEFAULTCOLLELEM
187 %token tDEFAULTVALUE
188 %token tDEFAULTVTABLE
189 %token tDISABLECONSISTENCYCHECK tDISPLAYBIND
190 %token tDISPINTERFACE
191 %token tDLLNAME tDOUBLE tDUAL
192 %token tENABLEALLOCATE tENCODE tENDPOINT
193 %token tENTRY tENUM tERRORSTATUST
194 %token tEXPLICITHANDLE tEXTERN
195 %token tFALSE
196 %token tFASTCALL tFAULTSTATUS
197 %token tFLOAT tFORCEALLOCATE
198 %token tHANDLE
199 %token tHANDLET
200 %token tHELPCONTEXT tHELPFILE
201 %token tHELPSTRING tHELPSTRINGCONTEXT tHELPSTRINGDLL
202 %token tHIDDEN
203 %token tHYPER tID tIDEMPOTENT
204 %token tIGNORE tIIDIS
205 %token tIMMEDIATEBIND
206 %token tIMPLICITHANDLE
207 %token tIMPORT tIMPORTLIB
208 %token tIN tIN_LINE tINLINE
209 %token tINPUTSYNC
210 %token tINT tINT3264 tINT64
211 %token tINTERFACE
212 %token tLCID
213 %token tLENGTHIS tLIBRARY
214 %token tLICENSED tLOCAL
215 %token tLONG
216 %token tMAYBE tMESSAGE
217 %token tMETHODS
218 %token tMODULE
219 %token tNAMESPACE
220 %token tNOCODE tNONBROWSABLE
221 %token tNONCREATABLE
222 %token tNONEXTENSIBLE
223 %token tNOTIFY tNOTIFYFLAG
224 %token tNULL
225 %token tOBJECT tODL tOLEAUTOMATION
226 %token tOPTIMIZE tOPTIONAL
227 %token tOUT
228 %token tPARTIALIGNORE tPASCAL
229 %token tPOINTERDEFAULT
230 %token tPRAGMA_WARNING
231 %token tPROGID tPROPERTIES
232 %token tPROPGET tPROPPUT tPROPPUTREF
233 %token tPROXY tPTR
234 %token tPUBLIC
235 %token tRANGE
236 %token tREADONLY tREF
237 %token tREGISTER tREPRESENTAS
238 %token tREQUESTEDIT
239 %token tRESTRICTED
240 %token tRETVAL
241 %token tSAFEARRAY
242 %token tSHORT
243 %token tSIGNED
244 %token tSIZEIS tSIZEOF
245 %token tSMALL
246 %token tSOURCE
247 %token tSTATIC
248 %token tSTDCALL
249 %token tSTRICTCONTEXTHANDLE
250 %token tSTRING tSTRUCT
251 %token tSWITCH tSWITCHIS tSWITCHTYPE
252 %token tTHREADING tTRANSMITAS
253 %token tTRUE
254 %token tTYPEDEF
255 %token tUIDEFAULT tUNION
256 %token tUNIQUE
257 %token tUNSIGNED
258 %token tUSESGETLASTERROR tUSERMARSHAL tUUID
259 %token tV1ENUM
260 %token tVARARG
261 %token tVERSION tVIPROGID
262 %token tVOID
263 %token tWCHAR tWIREMARSHAL
264 %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
265 
266 %type <attr> attribute type_qualifier function_specifier
267 %type <attr_list> m_attributes attributes attrib_list m_type_qual_list
268 %type <str_list> str_list
269 %type <expr> m_expr expr expr_const expr_int_const array m_bitfield
270 %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
271 %type <ifinfo> interfacehdr
272 %type <stgclass> storage_cls_spec
273 %type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
274 %type <type> inherit interface interfacedef interfacedec
275 %type <type> dispinterface dispinterfacehdr dispinterfacedef
276 %type <type> module modulehdr moduledef
277 %type <str> namespacedef
278 %type <type> base_type int_std
279 %type <type> enumdef structdef uniondef typedecl
280 %type <type> type
281 %type <ifref> coclass_int
282 %type <ifref_list> coclass_ints
283 %type <var> arg ne_union_field union_field s_field case enum declaration
284 %type <var> funcdef
285 %type <var_list> m_args arg_list args dispint_meths
286 %type <var_list> fields ne_union_fields cases enums enum_list dispint_props field
287 %type <var> m_ident ident
288 %type <declarator> declarator direct_declarator init_declarator struct_declarator
289 %type <declarator> m_any_declarator any_declarator any_declarator_no_direct any_direct_declarator
290 %type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator
291 %type <declarator_list> declarator_list struct_declarator_list
292 %type <type> coclass coclasshdr coclassdef
293 %type <num> pointer_type threading_type version
294 %type <str> libraryhdr callconv cppquote importlib import t_ident
295 %type <uuid> uuid_string
296 %type <import> import_start
297 %type <typelib> library_start librarydef
298 %type <statement> statement typedef pragma_warning
299 %type <stmt_list> gbl_statements imp_statements int_statements
300 %type <warning_list> warnings
301 
302 %left ','
303 %right '?' ':'
304 %left LOGICALOR
305 %left LOGICALAND
306 %left '|'
307 %left '^'
308 %left '&'
309 %left EQUALITY INEQUALITY
310 %left '<' '>' LESSEQUAL GREATEREQUAL
311 %left SHL SHR
312 %left '-' '+'
313 %left '*' '/' '%'
314 %right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
315 %left '.' MEMBERPTR '[' ']'
316 
317 %error-verbose
318 
319 %%
320 
321 input:   gbl_statements				{ fix_incomplete();
322 						  check_statements($1, FALSE);
323 						  check_all_user_types($1);
324 						  write_header($1);
325 						  write_id_data($1);
326 						  write_proxies($1);
327 						  write_client($1);
328 						  write_server($1);
329 						  write_regscript($1);
330 						  write_dlldata($1);
331 						  write_local_stubs($1);
332 						}
333 	;
334 
335 gbl_statements:					{ $$ = NULL; }
336 	| gbl_statements namespacedef '{' { push_namespace($2); } gbl_statements '}'
337 						{ pop_namespace($2); $$ = append_statements($1, $5); }
338 	| gbl_statements interfacedec		{ $$ = append_statement($1, make_statement_reference($2)); }
339 	| gbl_statements interfacedef		{ $$ = append_statement($1, make_statement_type_decl($2)); }
340 	| gbl_statements coclass ';'		{ $$ = $1;
341 						  reg_type($2, $2->name, current_namespace, 0);
342 						}
343 	| gbl_statements coclassdef		{ $$ = append_statement($1, make_statement_type_decl($2));
344 						  reg_type($2, $2->name, current_namespace, 0);
345 						}
346 	| gbl_statements moduledef		{ $$ = append_statement($1, make_statement_module($2)); }
347 	| gbl_statements librarydef		{ $$ = append_statement($1, make_statement_library($2)); }
348 	| gbl_statements statement		{ $$ = append_statement($1, $2); }
349 	;
350 
351 imp_statements:					{ $$ = NULL; }
352 	| imp_statements interfacedec		{ $$ = append_statement($1, make_statement_reference($2)); }
353 	| imp_statements namespacedef '{' { push_namespace($2); } imp_statements '}'
354 						{ pop_namespace($2); $$ = append_statements($1, $5); }
355 	| imp_statements interfacedef		{ $$ = append_statement($1, make_statement_type_decl($2)); }
356 	| imp_statements coclass ';'		{ $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
357 	| imp_statements coclassdef		{ $$ = append_statement($1, make_statement_type_decl($2));
358 						  reg_type($2, $2->name, current_namespace, 0);
359 						}
360 	| imp_statements moduledef		{ $$ = append_statement($1, make_statement_module($2)); }
361 	| imp_statements statement		{ $$ = append_statement($1, $2); }
362 	| imp_statements importlib		{ $$ = append_statement($1, make_statement_importlib($2)); }
363 	| imp_statements librarydef		{ $$ = append_statement($1, make_statement_library($2)); }
364 	;
365 
366 int_statements:					{ $$ = NULL; }
367 	| int_statements statement		{ $$ = append_statement($1, $2); }
368 	;
369 
370 semicolon_opt:
371 	| ';'
372 	;
373 
374 statement:
375 	  cppquote				{ $$ = make_statement_cppquote($1); }
376 	| typedecl ';'				{ $$ = make_statement_type_decl($1); }
377 	| declaration ';'			{ $$ = make_statement_declaration($1); }
378 	| import				{ $$ = make_statement_import($1); }
379 	| typedef ';'				{ $$ = $1; }
380 	| aPRAGMA				{ $$ = make_statement_pragma($1); }
381 	| pragma_warning { $$ = NULL; }
382 	;
383 
384 pragma_warning: tPRAGMA_WARNING '(' aIDENTIFIER ':' warnings ')'
385                   {
386                       int result;
387                       $$ = NULL;
388                       result = do_warning($3, $5);
389                       if(!result)
390                           error_loc("expected \"disable\" or \"enable\"\n");
391                   }
392 	;
393 
394 warnings:
395 	  aNUM { $$ = append_warning(NULL, $1); }
396 	| warnings aNUM { $$ = append_warning($1, $2); }
397 	;
398 
399 typedecl:
400 	  enumdef
401 	| tENUM aIDENTIFIER                     { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
402 	| structdef
403 	| tSTRUCT aIDENTIFIER                   { $$ = type_new_struct($2, current_namespace, FALSE, NULL); }
404 	| uniondef
405 	| tUNION aIDENTIFIER                    { $$ = type_new_nonencapsulated_union($2, FALSE, NULL); }
406 	| attributes enumdef                    { $$ = $2; $$->attrs = check_enum_attrs($1); }
407 	| attributes structdef                  { $$ = $2; $$->attrs = check_struct_attrs($1); }
408 	| attributes uniondef                   { $$ = $2; $$->attrs = check_union_attrs($1); }
409 	;
410 
411 cppquote: tCPPQUOTE '(' aSTRING ')'		{ $$ = $3; }
412 	;
413 import_start: tIMPORT aSTRING ';'		{ assert(yychar == YYEMPTY);
414 						  $$ = xmalloc(sizeof(struct _import_t));
415 						  $$->name = $2;
416 						  $$->import_performed = do_import($2);
417 						  if (!$$->import_performed) yychar = aEOF;
418 						}
419 	;
420 
421 import: import_start imp_statements aEOF	{ $$ = $1->name;
422 						  if ($1->import_performed) pop_import();
423 						  free($1);
424 						}
425 	;
426 
427 importlib: tIMPORTLIB '(' aSTRING ')'
428 	   semicolon_opt			{ $$ = $3; if(!parse_only) add_importlib($3); }
429 	;
430 
431 libraryhdr: tLIBRARY aIDENTIFIER		{ $$ = $2; }
432 	|   tLIBRARY aKNOWNTYPE			{ $$ = $2; }
433 	;
434 library_start: attributes libraryhdr '{'	{ $$ = make_library($2, check_library_attrs($2, $1));
435 						  if (!parse_only) start_typelib($$);
436 						}
437 	;
438 librarydef: library_start imp_statements '}'
439 	    semicolon_opt			{ $$ = $1;
440 						  $$->stmts = $2;
441 						  if (!parse_only) end_typelib();
442 						}
443 	;
444 
445 m_args:						{ $$ = NULL; }
446 	| args
447 	;
448 
449 arg_list: arg					{ check_arg_attrs($1); $$ = append_var( NULL, $1 ); }
450 	| arg_list ',' arg			{ check_arg_attrs($3); $$ = append_var( $1, $3 ); }
451 	;
452 
453 args:	  arg_list
454 	| arg_list ',' ELLIPSIS			{ $$ = append_var( $1, make_var(strdup("...")) ); }
455 	;
456 
457 /* split into two rules to get bison to resolve a tVOID conflict */
458 arg:	  attributes decl_spec m_any_declarator	{ if ($2->stgclass != STG_NONE && $2->stgclass != STG_REGISTER)
459 						    error_loc("invalid storage class for function parameter\n");
460 						  $$ = declare_var($1, $2, $3, TRUE);
461 						  free($2); free($3);
462 						}
463 	| decl_spec m_any_declarator		{ if ($1->stgclass != STG_NONE && $1->stgclass != STG_REGISTER)
464 						    error_loc("invalid storage class for function parameter\n");
465 						  $$ = declare_var(NULL, $1, $2, TRUE);
466 						  free($1); free($2);
467 						}
468 	;
469 
470 array:	  '[' expr ']'				{ $$ = $2;
471 						  if (!$$->is_const)
472 						      error_loc("array dimension is not an integer constant\n");
473 						}
474 	| '[' '*' ']'				{ $$ = make_expr(EXPR_VOID); }
475 	| '[' ']'				{ $$ = make_expr(EXPR_VOID); }
476 	;
477 
478 m_attributes:					{ $$ = NULL; }
479 	| attributes
480 	;
481 
482 attributes:
483 	  '[' attrib_list ']'			{ $$ = $2; }
484 	;
485 
486 attrib_list: attribute                          { $$ = append_attr( NULL, $1 ); }
487 	| attrib_list ',' attribute             { $$ = append_attr( $1, $3 ); }
488 	| attrib_list ']' '[' attribute         { $$ = append_attr( $1, $4 ); }
489 	;
490 
491 str_list: aSTRING                               { $$ = append_str( NULL, $1 ); }
492 	| str_list ',' aSTRING                  { $$ = append_str( $1, $3 ); }
493 	;
494 
495 attribute:					{ $$ = NULL; }
496 	| tAGGREGATABLE				{ $$ = make_attr(ATTR_AGGREGATABLE); }
497 	| tANNOTATION '(' aSTRING ')'		{ $$ = make_attrp(ATTR_ANNOTATION, $3); }
498 	| tAPPOBJECT				{ $$ = make_attr(ATTR_APPOBJECT); }
499 	| tASYNC				{ $$ = make_attr(ATTR_ASYNC); }
500 	| tAUTOHANDLE				{ $$ = make_attr(ATTR_AUTO_HANDLE); }
501 	| tBINDABLE				{ $$ = make_attr(ATTR_BINDABLE); }
502 	| tBROADCAST				{ $$ = make_attr(ATTR_BROADCAST); }
503 	| tCALLAS '(' ident ')'			{ $$ = make_attrp(ATTR_CALLAS, $3); }
504 	| tCASE '(' expr_list_int_const ')'	{ $$ = make_attrp(ATTR_CASE, $3); }
505 	| tCODE					{ $$ = make_attr(ATTR_CODE); }
506 	| tCOMMSTATUS				{ $$ = make_attr(ATTR_COMMSTATUS); }
507 	| tCONTEXTHANDLE			{ $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
508 	| tCONTEXTHANDLENOSERIALIZE		{ $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
509 	| tCONTEXTHANDLESERIALIZE		{ $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
510 	| tCONTROL				{ $$ = make_attr(ATTR_CONTROL); }
511 	| tDECODE				{ $$ = make_attr(ATTR_DECODE); }
512 	| tDEFAULT				{ $$ = make_attr(ATTR_DEFAULT); }
513 	| tDEFAULTBIND				{ $$ = make_attr(ATTR_DEFAULTBIND); }
514 	| tDEFAULTCOLLELEM			{ $$ = make_attr(ATTR_DEFAULTCOLLELEM); }
515 	| tDEFAULTVALUE '(' expr_const ')'	{ $$ = make_attrp(ATTR_DEFAULTVALUE, $3); }
516 	| tDEFAULTVTABLE			{ $$ = make_attr(ATTR_DEFAULTVTABLE); }
517 	| tDISABLECONSISTENCYCHECK		{ $$ = make_attr(ATTR_DISABLECONSISTENCYCHECK); }
518 	| tDISPLAYBIND				{ $$ = make_attr(ATTR_DISPLAYBIND); }
519 	| tDLLNAME '(' aSTRING ')'		{ $$ = make_attrp(ATTR_DLLNAME, $3); }
520 	| tDUAL					{ $$ = make_attr(ATTR_DUAL); }
521 	| tENABLEALLOCATE			{ $$ = make_attr(ATTR_ENABLEALLOCATE); }
522 	| tENCODE				{ $$ = make_attr(ATTR_ENCODE); }
523 	| tENDPOINT '(' str_list ')'		{ $$ = make_attrp(ATTR_ENDPOINT, $3); }
524 	| tENTRY '(' expr_const ')'		{ $$ = make_attrp(ATTR_ENTRY, $3); }
525 	| tEXPLICITHANDLE			{ $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
526 	| tFAULTSTATUS				{ $$ = make_attr(ATTR_FAULTSTATUS); }
527 	| tFORCEALLOCATE			{ $$ = make_attr(ATTR_FORCEALLOCATE); }
528 	| tHANDLE				{ $$ = make_attr(ATTR_HANDLE); }
529 	| tHELPCONTEXT '(' expr_int_const ')'	{ $$ = make_attrp(ATTR_HELPCONTEXT, $3); }
530 	| tHELPFILE '(' aSTRING ')'		{ $$ = make_attrp(ATTR_HELPFILE, $3); }
531 	| tHELPSTRING '(' aSTRING ')'		{ $$ = make_attrp(ATTR_HELPSTRING, $3); }
532 	| tHELPSTRINGCONTEXT '(' expr_int_const ')'	{ $$ = make_attrp(ATTR_HELPSTRINGCONTEXT, $3); }
533 	| tHELPSTRINGDLL '(' aSTRING ')'	{ $$ = make_attrp(ATTR_HELPSTRINGDLL, $3); }
534 	| tHIDDEN				{ $$ = make_attr(ATTR_HIDDEN); }
535 	| tID '(' expr_int_const ')'		{ $$ = make_attrp(ATTR_ID, $3); }
536 	| tIDEMPOTENT				{ $$ = make_attr(ATTR_IDEMPOTENT); }
537 	| tIGNORE				{ $$ = make_attr(ATTR_IGNORE); }
538 	| tIIDIS '(' expr ')'			{ $$ = make_attrp(ATTR_IIDIS, $3); }
539 	| tIMMEDIATEBIND			{ $$ = make_attr(ATTR_IMMEDIATEBIND); }
540 	| tIMPLICITHANDLE '(' arg ')'		{ $$ = make_attrp(ATTR_IMPLICIT_HANDLE, $3); }
541 	| tIN					{ $$ = make_attr(ATTR_IN); }
542 	| tINPUTSYNC				{ $$ = make_attr(ATTR_INPUTSYNC); }
543 	| tLENGTHIS '(' m_exprs ')'		{ $$ = make_attrp(ATTR_LENGTHIS, $3); }
544 	| tLCID	'(' expr_int_const ')'		{ $$ = make_attrp(ATTR_LIBLCID, $3); }
545 	| tLCID					{ $$ = make_attr(ATTR_PARAMLCID); }
546 	| tLICENSED				{ $$ = make_attr(ATTR_LICENSED); }
547 	| tLOCAL				{ $$ = make_attr(ATTR_LOCAL); }
548 	| tMAYBE				{ $$ = make_attr(ATTR_MAYBE); }
549 	| tMESSAGE				{ $$ = make_attr(ATTR_MESSAGE); }
550 	| tNOCODE				{ $$ = make_attr(ATTR_NOCODE); }
551 	| tNONBROWSABLE				{ $$ = make_attr(ATTR_NONBROWSABLE); }
552 	| tNONCREATABLE				{ $$ = make_attr(ATTR_NONCREATABLE); }
553 	| tNONEXTENSIBLE			{ $$ = make_attr(ATTR_NONEXTENSIBLE); }
554 	| tNOTIFY				{ $$ = make_attr(ATTR_NOTIFY); }
555 	| tNOTIFYFLAG				{ $$ = make_attr(ATTR_NOTIFYFLAG); }
556 	| tOBJECT				{ $$ = make_attr(ATTR_OBJECT); }
557 	| tODL					{ $$ = make_attr(ATTR_ODL); }
558 	| tOLEAUTOMATION			{ $$ = make_attr(ATTR_OLEAUTOMATION); }
559 	| tOPTIMIZE '(' aSTRING ')'		{ $$ = make_attrp(ATTR_OPTIMIZE, $3); }
560 	| tOPTIONAL                             { $$ = make_attr(ATTR_OPTIONAL); }
561 	| tOUT					{ $$ = make_attr(ATTR_OUT); }
562 	| tPARTIALIGNORE			{ $$ = make_attr(ATTR_PARTIALIGNORE); }
563 	| tPOINTERDEFAULT '(' pointer_type ')'	{ $$ = make_attrv(ATTR_POINTERDEFAULT, $3); }
564 	| tPROGID '(' aSTRING ')'		{ $$ = make_attrp(ATTR_PROGID, $3); }
565 	| tPROPGET				{ $$ = make_attr(ATTR_PROPGET); }
566 	| tPROPPUT				{ $$ = make_attr(ATTR_PROPPUT); }
567 	| tPROPPUTREF				{ $$ = make_attr(ATTR_PROPPUTREF); }
568 	| tPROXY				{ $$ = make_attr(ATTR_PROXY); }
569 	| tPUBLIC				{ $$ = make_attr(ATTR_PUBLIC); }
570 	| tRANGE '(' expr_int_const ',' expr_int_const ')'
571 						{ expr_list_t *list = append_expr( NULL, $3 );
572 						  list = append_expr( list, $5 );
573 						  $$ = make_attrp(ATTR_RANGE, list); }
574 	| tREADONLY				{ $$ = make_attr(ATTR_READONLY); }
575 	| tREPRESENTAS '(' type ')'		{ $$ = make_attrp(ATTR_REPRESENTAS, $3); }
576 	| tREQUESTEDIT				{ $$ = make_attr(ATTR_REQUESTEDIT); }
577 	| tRESTRICTED				{ $$ = make_attr(ATTR_RESTRICTED); }
578 	| tRETVAL				{ $$ = make_attr(ATTR_RETVAL); }
579 	| tSIZEIS '(' m_exprs ')'		{ $$ = make_attrp(ATTR_SIZEIS, $3); }
580 	| tSOURCE				{ $$ = make_attr(ATTR_SOURCE); }
581 	| tSTRICTCONTEXTHANDLE                  { $$ = make_attr(ATTR_STRICTCONTEXTHANDLE); }
582 	| tSTRING				{ $$ = make_attr(ATTR_STRING); }
583 	| tSWITCHIS '(' expr ')'		{ $$ = make_attrp(ATTR_SWITCHIS, $3); }
584 	| tSWITCHTYPE '(' type ')'		{ $$ = make_attrp(ATTR_SWITCHTYPE, $3); }
585 	| tTRANSMITAS '(' type ')'		{ $$ = make_attrp(ATTR_TRANSMITAS, $3); }
586 	| tTHREADING '(' threading_type ')'	{ $$ = make_attrv(ATTR_THREADING, $3); }
587 	| tUIDEFAULT				{ $$ = make_attr(ATTR_UIDEFAULT); }
588 	| tUSESGETLASTERROR			{ $$ = make_attr(ATTR_USESGETLASTERROR); }
589 	| tUSERMARSHAL '(' type ')'		{ $$ = make_attrp(ATTR_USERMARSHAL, $3); }
590 	| tUUID '(' uuid_string ')'		{ $$ = make_attrp(ATTR_UUID, $3); }
591 	| tASYNCUUID '(' uuid_string ')'	{ $$ = make_attrp(ATTR_ASYNCUUID, $3); }
592 	| tV1ENUM				{ $$ = make_attr(ATTR_V1ENUM); }
593 	| tVARARG				{ $$ = make_attr(ATTR_VARARG); }
594 	| tVERSION '(' version ')'		{ $$ = make_attrv(ATTR_VERSION, $3); }
595 	| tVIPROGID '(' aSTRING ')'		{ $$ = make_attrp(ATTR_VIPROGID, $3); }
596 	| tWIREMARSHAL '(' type ')'		{ $$ = make_attrp(ATTR_WIREMARSHAL, $3); }
597 	| pointer_type				{ $$ = make_attrv(ATTR_POINTERTYPE, $1); }
598 	;
599 
600 uuid_string:
601 	  aUUID
602 	| aSTRING				{ if (!is_valid_uuid($1))
603 						    error_loc("invalid UUID: %s\n", $1);
604 						  $$ = parse_uuid($1); }
605         ;
606 
607 callconv: tCDECL				{ $$ = xstrdup("__cdecl"); }
608 	| tFASTCALL				{ $$ = xstrdup("__fastcall"); }
609 	| tPASCAL				{ $$ = xstrdup("__pascal"); }
610 	| tSTDCALL				{ $$ = xstrdup("__stdcall"); }
611 	;
612 
613 cases:						{ $$ = NULL; }
614 	| cases case				{ $$ = append_var( $1, $2 ); }
615 	;
616 
617 case:	  tCASE expr_int_const ':' union_field	{ attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 ));
618 						  $$ = $4; if (!$$) $$ = make_var(NULL);
619 						  $$->attrs = append_attr( $$->attrs, a );
620 						}
621 	| tDEFAULT ':' union_field		{ attr_t *a = make_attr(ATTR_DEFAULT);
622 						  $$ = $3; if (!$$) $$ = make_var(NULL);
623 						  $$->attrs = append_attr( $$->attrs, a );
624 						}
625 	;
626 
627 enums:						{ $$ = NULL; }
628 	| enum_list ','				{ $$ = $1; }
629 	| enum_list
630 	;
631 
632 enum_list: enum					{ if (!$1->eval)
633 						    $1->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
634                                                   $$ = append_var( NULL, $1 );
635 						}
636 	| enum_list ',' enum			{ if (!$3->eval)
637                                                   {
638                                                     var_t *last = LIST_ENTRY( list_tail($$), var_t, entry );
639                                                     enum expr_type type = EXPR_NUM;
640                                                     if (last->eval->type == EXPR_HEXNUM) type = EXPR_HEXNUM;
641                                                     if (last->eval->cval + 1 < 0) type = EXPR_HEXNUM;
642                                                     $3->eval = make_exprl(type, last->eval->cval + 1);
643                                                   }
644                                                   $$ = append_var( $1, $3 );
645 						}
646 	;
647 
648 enum:	  ident '=' expr_int_const		{ $$ = reg_const($1);
649 						  $$->eval = $3;
650                                                   $$->type = type_new_int(TYPE_BASIC_INT, 0);
651 						}
652 	| ident					{ $$ = reg_const($1);
653                                                   $$->type = type_new_int(TYPE_BASIC_INT, 0);
654 						}
655 	;
656 
657 enumdef: tENUM t_ident '{' enums '}'		{ $$ = type_new_enum($2, current_namespace, TRUE, $4); }
658 	;
659 
660 m_exprs:  m_expr                                { $$ = append_expr( NULL, $1 ); }
661 	| m_exprs ',' m_expr                    { $$ = append_expr( $1, $3 ); }
662 	;
663 
664 m_expr:						{ $$ = make_expr(EXPR_VOID); }
665 	| expr
666 	;
667 
668 expr:	  aNUM					{ $$ = make_exprl(EXPR_NUM, $1); }
669 	| aHEXNUM				{ $$ = make_exprl(EXPR_HEXNUM, $1); }
670 	| aDOUBLE				{ $$ = make_exprd(EXPR_DOUBLE, $1); }
671 	| tFALSE				{ $$ = make_exprl(EXPR_TRUEFALSE, 0); }
672 	| tNULL					{ $$ = make_exprl(EXPR_NUM, 0); }
673 	| tTRUE					{ $$ = make_exprl(EXPR_TRUEFALSE, 1); }
674 	| aSTRING				{ $$ = make_exprs(EXPR_STRLIT, $1); }
675 	| aWSTRING				{ $$ = make_exprs(EXPR_WSTRLIT, $1); }
676 	| aSQSTRING				{ $$ = make_exprs(EXPR_CHARCONST, $1); }
677 	| aIDENTIFIER				{ $$ = make_exprs(EXPR_IDENTIFIER, $1); }
678 	| expr '?' expr ':' expr		{ $$ = make_expr3(EXPR_COND, $1, $3, $5); }
679 	| expr LOGICALOR expr			{ $$ = make_expr2(EXPR_LOGOR, $1, $3); }
680 	| expr LOGICALAND expr			{ $$ = make_expr2(EXPR_LOGAND, $1, $3); }
681 	| expr '|' expr				{ $$ = make_expr2(EXPR_OR , $1, $3); }
682 	| expr '^' expr				{ $$ = make_expr2(EXPR_XOR, $1, $3); }
683 	| expr '&' expr				{ $$ = make_expr2(EXPR_AND, $1, $3); }
684 	| expr EQUALITY expr			{ $$ = make_expr2(EXPR_EQUALITY, $1, $3); }
685 	| expr INEQUALITY expr			{ $$ = make_expr2(EXPR_INEQUALITY, $1, $3); }
686 	| expr '>' expr				{ $$ = make_expr2(EXPR_GTR, $1, $3); }
687 	| expr '<' expr				{ $$ = make_expr2(EXPR_LESS, $1, $3); }
688 	| expr GREATEREQUAL expr		{ $$ = make_expr2(EXPR_GTREQL, $1, $3); }
689 	| expr LESSEQUAL expr			{ $$ = make_expr2(EXPR_LESSEQL, $1, $3); }
690 	| expr SHL expr				{ $$ = make_expr2(EXPR_SHL, $1, $3); }
691 	| expr SHR expr				{ $$ = make_expr2(EXPR_SHR, $1, $3); }
692 	| expr '+' expr				{ $$ = make_expr2(EXPR_ADD, $1, $3); }
693 	| expr '-' expr				{ $$ = make_expr2(EXPR_SUB, $1, $3); }
694 	| expr '%' expr				{ $$ = make_expr2(EXPR_MOD, $1, $3); }
695 	| expr '*' expr				{ $$ = make_expr2(EXPR_MUL, $1, $3); }
696 	| expr '/' expr				{ $$ = make_expr2(EXPR_DIV, $1, $3); }
697 	| '!' expr				{ $$ = make_expr1(EXPR_LOGNOT, $2); }
698 	| '~' expr				{ $$ = make_expr1(EXPR_NOT, $2); }
699 	| '+' expr %prec POS			{ $$ = make_expr1(EXPR_POS, $2); }
700 	| '-' expr %prec NEG			{ $$ = make_expr1(EXPR_NEG, $2); }
701 	| '&' expr %prec ADDRESSOF		{ $$ = make_expr1(EXPR_ADDRESSOF, $2); }
702 	| '*' expr %prec PPTR			{ $$ = make_expr1(EXPR_PPTR, $2); }
703 	| expr MEMBERPTR aIDENTIFIER		{ $$ = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, $1), make_exprs(EXPR_IDENTIFIER, $3)); }
704 	| expr '.' aIDENTIFIER			{ $$ = make_expr2(EXPR_MEMBER, $1, make_exprs(EXPR_IDENTIFIER, $3)); }
705 	| '(' decl_spec m_abstract_declarator ')' expr %prec CAST
706 						{ $$ = make_exprt(EXPR_CAST, declare_var(NULL, $2, $3, 0), $5); free($2); free($3); }
707 	| tSIZEOF '(' decl_spec m_abstract_declarator ')'
708 						{ $$ = make_exprt(EXPR_SIZEOF, declare_var(NULL, $3, $4, 0), NULL); free($3); free($4); }
709 	| expr '[' expr ']'			{ $$ = make_expr2(EXPR_ARRAY, $1, $3); }
710 	| '(' expr ')'				{ $$ = $2; }
711 	;
712 
713 expr_list_int_const: expr_int_const		{ $$ = append_expr( NULL, $1 ); }
714 	| expr_list_int_const ',' expr_int_const	{ $$ = append_expr( $1, $3 ); }
715 	;
716 
717 expr_int_const: expr				{ $$ = $1;
718 						  if (!$$->is_const)
719 						      error_loc("expression is not an integer constant\n");
720 						}
721 	;
722 
723 expr_const: expr				{ $$ = $1;
724 						  if (!$$->is_const && $$->type != EXPR_STRLIT && $$->type != EXPR_WSTRLIT)
725 						      error_loc("expression is not constant\n");
726 						}
727 	;
728 
729 fields:						{ $$ = NULL; }
730 	| fields field				{ $$ = append_var_list($1, $2); }
731 	;
732 
733 field:	  m_attributes decl_spec struct_declarator_list ';'
734 						{ const char *first = LIST_ENTRY(list_head($3), declarator_t, entry)->var->name;
735 						  check_field_attrs(first, $1);
736 						  $$ = set_var_types($1, $2, $3);
737 						}
738 	| m_attributes uniondef ';'		{ var_t *v = make_var(NULL);
739 						  v->type = $2; v->attrs = $1;
740 						  $$ = append_var(NULL, v);
741 						}
742 	;
743 
744 ne_union_field:
745 	  s_field ';'				{ $$ = $1; }
746 	| attributes ';'			{ $$ = make_var(NULL); $$->attrs = $1; }
747         ;
748 
749 ne_union_fields:				{ $$ = NULL; }
750 	| ne_union_fields ne_union_field	{ $$ = append_var( $1, $2 ); }
751 	;
752 
753 union_field:
754 	  s_field ';'				{ $$ = $1; }
755 	| ';'					{ $$ = NULL; }
756         ;
757 
758 s_field:  m_attributes decl_spec declarator	{ $$ = declare_var(check_field_attrs($3->var->name, $1),
759 						                $2, $3, FALSE);
760 						  free($3);
761 						}
762 	| m_attributes structdef		{ var_t *v = make_var(NULL);
763 						  v->type = $2; v->attrs = $1;
764 						  $$ = v;
765 						}
766 	;
767 
768 funcdef: declaration				{ $$ = $1;
769 						  if (type_get_type($$->type) != TYPE_FUNCTION)
770 						    error_loc("only methods may be declared inside the methods section of a dispinterface\n");
771 						  check_function_attrs($$->name, $$->attrs);
772 						}
773 	;
774 
775 declaration:
776 	  attributes decl_spec init_declarator
777 						{ $$ = declare_var($1, $2, $3, FALSE);
778 						  free($3);
779 						}
780 	| decl_spec init_declarator		{ $$ = declare_var(NULL, $1, $2, FALSE);
781 						  free($2);
782 						}
783 	;
784 
785 m_ident:					{ $$ = NULL; }
786 	| ident
787 	;
788 
789 t_ident:					{ $$ = NULL; }
790 	| aIDENTIFIER				{ $$ = $1; }
791 	| aKNOWNTYPE				{ $$ = $1; }
792 	;
793 
794 ident:	  aIDENTIFIER				{ $$ = make_var($1); }
795 /* some "reserved words" used in attributes are also used as field names in some MS IDL files */
796 	| aKNOWNTYPE				{ $$ = make_var($<str>1); }
797 	;
798 
799 base_type: tBYTE				{ $$ = find_type_or_error($<str>1, 0); }
800 	| tWCHAR				{ $$ = find_type_or_error($<str>1, 0); }
801 	| int_std
802 	| tSIGNED int_std			{ $$ = type_new_int(type_basic_get_type($2), -1); }
803 	| tUNSIGNED int_std			{ $$ = type_new_int(type_basic_get_type($2), 1); }
804 	| tUNSIGNED				{ $$ = type_new_int(TYPE_BASIC_INT, 1); }
805 	| tFLOAT				{ $$ = find_type_or_error($<str>1, 0); }
806 	| tDOUBLE				{ $$ = find_type_or_error($<str>1, 0); }
807 	| tBOOLEAN				{ $$ = find_type_or_error($<str>1, 0); }
808 	| tERRORSTATUST				{ $$ = find_type_or_error($<str>1, 0); }
809 	| tHANDLET				{ $$ = find_type_or_error($<str>1, 0); }
810 	;
811 
812 m_int:
813 	| tINT
814 	;
815 
816 int_std:  tINT					{ $$ = type_new_int(TYPE_BASIC_INT, 0); }
817 	| tSHORT m_int				{ $$ = type_new_int(TYPE_BASIC_INT16, 0); }
818 	| tSMALL				{ $$ = type_new_int(TYPE_BASIC_INT8, 0); }
819 	| tLONG m_int				{ $$ = type_new_int(TYPE_BASIC_INT32, 0); }
820 	| tHYPER m_int				{ $$ = type_new_int(TYPE_BASIC_HYPER, 0); }
821 	| tINT64				{ $$ = type_new_int(TYPE_BASIC_INT64, 0); }
822 	| tCHAR					{ $$ = type_new_int(TYPE_BASIC_CHAR, 0); }
823 	| tINT3264				{ $$ = type_new_int(TYPE_BASIC_INT3264, 0); }
824 	;
825 
826 coclass:  tCOCLASS aIDENTIFIER			{ $$ = type_new_coclass($2); }
827 	| tCOCLASS aKNOWNTYPE			{ $$ = find_type($2, NULL, 0);
828 						  if (type_get_type_detect_alias($$) != TYPE_COCLASS)
829 						    error_loc("%s was not declared a coclass at %s:%d\n",
830 							      $2, $$->loc_info.input_name,
831 							      $$->loc_info.line_number);
832 						}
833 	;
834 
835 coclasshdr: attributes coclass			{ $$ = $2;
836 						  check_def($$);
837 						  $$->attrs = check_coclass_attrs($2->name, $1);
838 						}
839 	;
840 
841 coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
842 						{ $$ = type_coclass_define($1, $3); }
843 	;
844 
845 namespacedef: tNAMESPACE aIDENTIFIER		{ $$ = $2; }
846 	;
847 
848 coclass_ints:					{ $$ = NULL; }
849 	| coclass_ints coclass_int		{ $$ = append_ifref( $1, $2 ); }
850 	;
851 
852 coclass_int:
853 	  m_attributes interfacedec		{ $$ = make_ifref($2); $$->attrs = $1; }
854 	;
855 
856 dispinterface: tDISPINTERFACE aIDENTIFIER	{ $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
857 	|      tDISPINTERFACE aKNOWNTYPE	{ $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
858 	;
859 
860 dispinterfacehdr: attributes dispinterface	{ attr_t *attrs;
861 						  $$ = $2;
862 						  check_def($$);
863 						  attrs = make_attr(ATTR_DISPINTERFACE);
864 						  $$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
865 						  $$->defined = TRUE;
866 						}
867 	;
868 
869 dispint_props: tPROPERTIES ':'			{ $$ = NULL; }
870 	| dispint_props s_field ';'		{ $$ = append_var( $1, $2 ); }
871 	;
872 
873 dispint_meths: tMETHODS ':'			{ $$ = NULL; }
874 	| dispint_meths funcdef ';'		{ $$ = append_var( $1, $2 ); }
875 	;
876 
877 dispinterfacedef: dispinterfacehdr '{'
878 	  dispint_props
879 	  dispint_meths
880 	  '}'					{ $$ = $1;
881 						  type_dispinterface_define($$, $3, $4);
882 						}
883 	| dispinterfacehdr
884 	 '{' interface ';' '}' 			{ $$ = $1;
885 						  type_dispinterface_define_from_iface($$, $3);
886 						}
887 	;
888 
889 inherit:					{ $$ = NULL; }
890 	| ':' aKNOWNTYPE			{ $$ = find_type_or_error2($2, 0); }
891 	;
892 
893 interface: tINTERFACE aIDENTIFIER		{ $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
894 	|  tINTERFACE aKNOWNTYPE		{ $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
895 	;
896 
897 interfacehdr: attributes interface		{ $$.interface = $2;
898 						  $$.old_pointer_default = pointer_default;
899 						  if (is_attr($1, ATTR_POINTERDEFAULT))
900 						    pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
901 						  check_def($2);
902 						  $2->attrs = check_iface_attrs($2->name, $1);
903 						  $2->defined = TRUE;
904 						}
905 	;
906 
907 interfacedef: interfacehdr inherit
908 	  '{' int_statements '}' semicolon_opt	{ $$ = $1.interface;
909 						  if($$ == $2)
910 						    error_loc("Interface can't inherit from itself\n");
911 						  type_interface_define($$, $2, $4);
912 						  pointer_default = $1.old_pointer_default;
913 						}
914 /* MIDL is able to import the definition of a base class from inside the
915  * definition of a derived class, I'll try to support it with this rule */
916 	| interfacehdr ':' aIDENTIFIER
917 	  '{' import int_statements '}'
918 	   semicolon_opt			{ $$ = $1.interface;
919 						  type_interface_define($$, find_type_or_error2($3, 0), $6);
920 						  pointer_default = $1.old_pointer_default;
921 						}
922 	| dispinterfacedef semicolon_opt	{ $$ = $1; }
923 	;
924 
925 interfacedec:
926 	  interface ';'				{ $$ = $1; }
927 	| dispinterface ';'			{ $$ = $1; }
928 	;
929 
930 module:   tMODULE aIDENTIFIER			{ $$ = type_new_module($2); }
931 	| tMODULE aKNOWNTYPE			{ $$ = type_new_module($2); }
932 	;
933 
934 modulehdr: attributes module			{ $$ = $2;
935 						  $$->attrs = check_module_attrs($2->name, $1);
936 						}
937 	;
938 
939 moduledef: modulehdr '{' int_statements '}'
940 	   semicolon_opt			{ $$ = $1;
941                                                   type_module_define($$, $3);
942 						}
943 	;
944 
945 storage_cls_spec:
946 	  tEXTERN				{ $$ = STG_EXTERN; }
947 	| tSTATIC				{ $$ = STG_STATIC; }
948 	| tREGISTER				{ $$ = STG_REGISTER; }
949 	;
950 
951 function_specifier:
952 	  tINLINE				{ $$ = make_attr(ATTR_INLINE); }
953 	;
954 
955 type_qualifier:
956 	  tCONST				{ $$ = make_attr(ATTR_CONST); }
957 	;
958 
959 m_type_qual_list:				{ $$ = NULL; }
960 	| m_type_qual_list type_qualifier	{ $$ = append_attr($1, $2); }
961 	;
962 
963 decl_spec: type m_decl_spec_no_type		{ $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); }
964 	| decl_spec_no_type type m_decl_spec_no_type
965 						{ $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); }
966 	;
967 
968 m_decl_spec_no_type:				{ $$ = NULL; }
969 	| decl_spec_no_type
970 	;
971 
972 decl_spec_no_type:
973 	  type_qualifier m_decl_spec_no_type	{ $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
974 	| function_specifier m_decl_spec_no_type  { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
975 	| storage_cls_spec m_decl_spec_no_type  { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); }
976 	;
977 
978 declarator:
979 	  '*' m_type_qual_list declarator %prec PPTR
980 						{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
981 	| callconv declarator			{ $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
982 						           else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
983 	| direct_declarator
984 	;
985 
986 direct_declarator:
987 	  ident					{ $$ = make_declarator($1); }
988 	| '(' declarator ')'			{ $$ = $2; }
989 	| direct_declarator array		{ $$ = $1; $$->array = append_array($$->array, $2); }
990 	| direct_declarator '(' m_args ')'	{ $$ = $1;
991 						  $$->func_type = append_ptrchain_type($$->type, type_new_function($3));
992 						  $$->type = NULL;
993 						}
994 	;
995 
996 /* abstract declarator */
997 abstract_declarator:
998 	  '*' m_type_qual_list m_abstract_declarator %prec PPTR
999 						{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
1000 	| callconv m_abstract_declarator	{ $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
1001 						           else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
1002 	| abstract_direct_declarator
1003 	;
1004 
1005 /* abstract declarator without accepting direct declarator */
1006 abstract_declarator_no_direct:
1007 	  '*' m_type_qual_list m_any_declarator %prec PPTR
1008 						{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
1009 	| callconv m_any_declarator		{ $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
1010 						           else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
1011 	;
1012 
1013 /* abstract declarator or empty */
1014 m_abstract_declarator: 				{ $$ = make_declarator(NULL); }
1015 	| abstract_declarator
1016 	;
1017 
1018 /* abstract direct declarator */
1019 abstract_direct_declarator:
1020 	  '(' abstract_declarator_no_direct ')'	{ $$ = $2; }
1021 	| abstract_direct_declarator array	{ $$ = $1; $$->array = append_array($$->array, $2); }
1022 	| array					{ $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); }
1023 	| '(' m_args ')'
1024 						{ $$ = make_declarator(NULL);
1025 						  $$->func_type = append_ptrchain_type($$->type, type_new_function($2));
1026 						  $$->type = NULL;
1027 						}
1028 	| abstract_direct_declarator '(' m_args ')'
1029 						{ $$ = $1;
1030 						  $$->func_type = append_ptrchain_type($$->type, type_new_function($3));
1031 						  $$->type = NULL;
1032 						}
1033 	;
1034 
1035 /* abstract or non-abstract declarator */
1036 any_declarator:
1037 	  '*' m_type_qual_list m_any_declarator %prec PPTR
1038 						{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
1039 	| callconv m_any_declarator		{ $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
1040 	| any_direct_declarator
1041 	;
1042 
1043 /* abstract or non-abstract declarator without accepting direct declarator */
1044 any_declarator_no_direct:
1045 	  '*' m_type_qual_list m_any_declarator %prec PPTR
1046 						{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
1047 	| callconv m_any_declarator		{ $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
1048 	;
1049 
1050 /* abstract or non-abstract declarator or empty */
1051 m_any_declarator: 				{ $$ = make_declarator(NULL); }
1052 	| any_declarator
1053 	;
1054 
1055 /* abstract or non-abstract direct declarator. note: direct declarators
1056  * aren't accepted inside brackets to avoid ambiguity with the rule for
1057  * function arguments */
1058 any_direct_declarator:
1059 	  ident					{ $$ = make_declarator($1); }
1060 	| '(' any_declarator_no_direct ')'	{ $$ = $2; }
1061 	| any_direct_declarator array		{ $$ = $1; $$->array = append_array($$->array, $2); }
1062 	| array					{ $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); }
1063 	| '(' m_args ')'
1064 						{ $$ = make_declarator(NULL);
1065 						  $$->func_type = append_ptrchain_type($$->type, type_new_function($2));
1066 						  $$->type = NULL;
1067 						}
1068 	| any_direct_declarator '(' m_args ')'
1069 						{ $$ = $1;
1070 						  $$->func_type = append_ptrchain_type($$->type, type_new_function($3));
1071 						  $$->type = NULL;
1072 						}
1073 	;
1074 
1075 declarator_list:
1076 	  declarator				{ $$ = append_declarator( NULL, $1 ); }
1077 	| declarator_list ',' declarator	{ $$ = append_declarator( $1, $3 ); }
1078 	;
1079 
1080 m_bitfield:					{ $$ = NULL; }
1081 	| ':' expr_const			{ $$ = $2; }
1082 	;
1083 
1084 struct_declarator: any_declarator m_bitfield	{ $$ = $1; $$->bits = $2;
1085 						  if (!$$->bits && !$$->var->name)
1086 						    error_loc("unnamed fields are not allowed\n");
1087 						}
1088 	;
1089 
1090 struct_declarator_list:
1091 	  struct_declarator			{ $$ = append_declarator( NULL, $1 ); }
1092 	| struct_declarator_list ',' struct_declarator
1093 						{ $$ = append_declarator( $1, $3 ); }
1094 	;
1095 
1096 init_declarator:
1097 	  declarator				{ $$ = $1; }
1098 	| declarator '=' expr_const		{ $$ = $1; $1->var->eval = $3; }
1099 	;
1100 
1101 threading_type:
1102 	  tAPARTMENT				{ $$ = THREADING_APARTMENT; }
1103 	| tNEUTRAL				{ $$ = THREADING_NEUTRAL; }
1104 	| tSINGLE				{ $$ = THREADING_SINGLE; }
1105 	| tFREE					{ $$ = THREADING_FREE; }
1106 	| tBOTH					{ $$ = THREADING_BOTH; }
1107 	;
1108 
1109 pointer_type:
1110 	  tREF					{ $$ = RPC_FC_RP; }
1111 	| tUNIQUE				{ $$ = RPC_FC_UP; }
1112 	| tPTR					{ $$ = RPC_FC_FP; }
1113 	;
1114 
1115 structdef: tSTRUCT t_ident '{' fields '}'	{ $$ = type_new_struct($2, current_namespace, TRUE, $4); }
1116 	;
1117 
1118 type:	  tVOID					{ $$ = type_new_void(); }
1119 	| aKNOWNTYPE				{ $$ = find_type_or_error($1, 0); }
1120 	| base_type				{ $$ = $1; }
1121 	| enumdef				{ $$ = $1; }
1122 	| tENUM aIDENTIFIER			{ $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
1123 	| structdef				{ $$ = $1; }
1124 	| tSTRUCT aIDENTIFIER			{ $$ = type_new_struct($2, current_namespace, FALSE, NULL); }
1125 	| uniondef				{ $$ = $1; }
1126 	| tUNION aIDENTIFIER			{ $$ = type_new_nonencapsulated_union($2, FALSE, NULL); }
1127 	| tSAFEARRAY '(' type ')'		{ $$ = make_safearray($3); }
1128 	;
1129 
1130 typedef: m_attributes tTYPEDEF m_attributes decl_spec declarator_list
1131 						{ $1 = append_attribs($1, $3);
1132 						  reg_typedefs($4, $5, check_typedef_attrs($1));
1133 						  $$ = make_statement_typedef($5);
1134 						}
1135 	;
1136 
1137 uniondef: tUNION t_ident '{' ne_union_fields '}'
1138 						{ $$ = type_new_nonencapsulated_union($2, TRUE, $4); }
1139 	| tUNION t_ident
1140 	  tSWITCH '(' s_field ')'
1141 	  m_ident '{' cases '}'			{ $$ = type_new_encapsulated_union($2, $5, $7, $9); }
1142 	;
1143 
1144 version:
1145 	  aNUM					{ $$ = MAKEVERSION($1, 0); }
1146 	| aNUM '.' aNUM				{ $$ = MAKEVERSION($1, $3); }
1147 	| aHEXNUM				{ $$ = $1; }
1148 	;
1149 
1150 %%
1151 
1152 static void decl_builtin_basic(const char *name, enum type_basic_type type)
1153 {
1154   type_t *t = type_new_basic(type);
1155   reg_type(t, name, NULL, 0);
1156 }
1157 
1158 static void decl_builtin_alias(const char *name, type_t *t)
1159 {
1160   reg_type(type_new_alias(t, name), name, NULL, 0);
1161 }
1162 
1163 void init_types(void)
1164 {
1165   decl_builtin_basic("byte", TYPE_BASIC_BYTE);
1166   decl_builtin_basic("wchar_t", TYPE_BASIC_WCHAR);
1167   decl_builtin_basic("float", TYPE_BASIC_FLOAT);
1168   decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
1169   decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
1170   decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
1171   decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
1172 }
1173 
1174 static str_list_t *append_str(str_list_t *list, char *str)
1175 {
1176     struct str_list_entry_t *entry;
1177 
1178     if (!str) return list;
1179     if (!list)
1180     {
1181         list = xmalloc( sizeof(*list) );
1182         list_init( list );
1183     }
1184     entry = xmalloc( sizeof(*entry) );
1185     entry->str = str;
1186     list_add_tail( list, &entry->entry );
1187     return list;
1188 }
1189 
1190 static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
1191 {
1192     attr_t *attr_existing;
1193     if (!attr) return list;
1194     if (!list)
1195     {
1196         list = xmalloc( sizeof(*list) );
1197         list_init( list );
1198     }
1199     LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
1200         if (attr_existing->type == attr->type)
1201         {
1202             parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
1203             /* use the last attribute, like MIDL does */
1204             list_remove(&attr_existing->entry);
1205             break;
1206         }
1207     list_add_tail( list, &attr->entry );
1208     return list;
1209 }
1210 
1211 static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
1212 {
1213   attr_t *attr;
1214   if (!src) return dst;
1215   LIST_FOR_EACH_ENTRY(attr, src, attr_t, entry)
1216     if (attr->type == type)
1217     {
1218       list_remove(&attr->entry);
1219       return append_attr(dst, attr);
1220     }
1221   return dst;
1222 }
1223 
1224 static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list)
1225 {
1226   struct list *entry;
1227 
1228   if (!old_list) return new_list;
1229 
1230   while ((entry = list_head(old_list)))
1231   {
1232     attr_t *attr = LIST_ENTRY(entry, attr_t, entry);
1233     list_remove(entry);
1234     new_list = append_attr(new_list, attr);
1235   }
1236   return new_list;
1237 }
1238 
1239 static attr_list_t *dupattrs(const attr_list_t *list)
1240 {
1241   attr_list_t *new_list;
1242   const attr_t *attr;
1243 
1244   if (!list) return NULL;
1245 
1246   new_list = xmalloc( sizeof(*list) );
1247   list_init( new_list );
1248   LIST_FOR_EACH_ENTRY(attr, list, const attr_t, entry)
1249   {
1250     attr_t *new_attr = xmalloc(sizeof(*new_attr));
1251     *new_attr = *attr;
1252     list_add_tail(new_list, &new_attr->entry);
1253   }
1254   return new_list;
1255 }
1256 
1257 static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
1258 {
1259   decl_spec_t *declspec = left ? left : right;
1260   if (!declspec)
1261   {
1262     declspec = xmalloc(sizeof(*declspec));
1263     declspec->type = NULL;
1264     declspec->attrs = NULL;
1265     declspec->stgclass = STG_NONE;
1266   }
1267   declspec->type = type;
1268   if (left && declspec != left)
1269   {
1270     declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
1271     if (declspec->stgclass == STG_NONE)
1272       declspec->stgclass = left->stgclass;
1273     else if (left->stgclass != STG_NONE)
1274       error_loc("only one storage class can be specified\n");
1275     assert(!left->type);
1276     free(left);
1277   }
1278   if (right && declspec != right)
1279   {
1280     declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
1281     if (declspec->stgclass == STG_NONE)
1282       declspec->stgclass = right->stgclass;
1283     else if (right->stgclass != STG_NONE)
1284       error_loc("only one storage class can be specified\n");
1285     assert(!right->type);
1286     free(right);
1287   }
1288 
1289   declspec->attrs = append_attr(declspec->attrs, attr);
1290   if (declspec->stgclass == STG_NONE)
1291     declspec->stgclass = stgclass;
1292   else if (stgclass != STG_NONE)
1293     error_loc("only one storage class can be specified\n");
1294 
1295   /* apply attributes to type */
1296   if (type && declspec->attrs)
1297   {
1298     attr_list_t *attrs;
1299     declspec->type = duptype(type, 1);
1300     attrs = dupattrs(type->attrs);
1301     declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
1302     declspec->attrs = NULL;
1303   }
1304 
1305   return declspec;
1306 }
1307 
1308 static attr_t *make_attr(enum attr_type type)
1309 {
1310   attr_t *a = xmalloc(sizeof(attr_t));
1311   a->type = type;
1312   a->u.ival = 0;
1313   return a;
1314 }
1315 
1316 static attr_t *make_attrv(enum attr_type type, unsigned int val)
1317 {
1318   attr_t *a = xmalloc(sizeof(attr_t));
1319   a->type = type;
1320   a->u.ival = val;
1321   return a;
1322 }
1323 
1324 static attr_t *make_attrp(enum attr_type type, void *val)
1325 {
1326   attr_t *a = xmalloc(sizeof(attr_t));
1327   a->type = type;
1328   a->u.pval = val;
1329   return a;
1330 }
1331 
1332 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
1333 {
1334     if (!expr) return list;
1335     if (!list)
1336     {
1337         list = xmalloc( sizeof(*list) );
1338         list_init( list );
1339     }
1340     list_add_tail( list, &expr->entry );
1341     return list;
1342 }
1343 
1344 static array_dims_t *append_array(array_dims_t *list, expr_t *expr)
1345 {
1346     if (!expr) return list;
1347     if (!list)
1348     {
1349         list = xmalloc( sizeof(*list) );
1350         list_init( list );
1351     }
1352     list_add_tail( list, &expr->entry );
1353     return list;
1354 }
1355 
1356 static struct list type_pool = LIST_INIT(type_pool);
1357 typedef struct
1358 {
1359   type_t data;
1360   struct list link;
1361 } type_pool_node_t;
1362 
1363 type_t *alloc_type(void)
1364 {
1365   type_pool_node_t *node = xmalloc(sizeof *node);
1366   list_add_tail(&type_pool, &node->link);
1367   return &node->data;
1368 }
1369 
1370 void set_all_tfswrite(int val)
1371 {
1372   type_pool_node_t *node;
1373   LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link)
1374     node->data.tfswrite = val;
1375 }
1376 
1377 void clear_all_offsets(void)
1378 {
1379   type_pool_node_t *node;
1380   LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link)
1381     node->data.typestring_offset = node->data.ptrdesc = 0;
1382 }
1383 
1384 static void type_function_add_head_arg(type_t *type, var_t *arg)
1385 {
1386     if (!type->details.function->args)
1387     {
1388         type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
1389         list_init( type->details.function->args );
1390     }
1391     list_add_head( type->details.function->args, &arg->entry );
1392 }
1393 
1394 static int is_allowed_range_type(const type_t *type)
1395 {
1396     switch (type_get_type(type))
1397     {
1398     case TYPE_ENUM:
1399         return TRUE;
1400     case TYPE_BASIC:
1401         switch (type_basic_get_type(type))
1402         {
1403         case TYPE_BASIC_INT8:
1404         case TYPE_BASIC_INT16:
1405         case TYPE_BASIC_INT32:
1406         case TYPE_BASIC_INT64:
1407         case TYPE_BASIC_INT:
1408         case TYPE_BASIC_INT3264:
1409         case TYPE_BASIC_BYTE:
1410         case TYPE_BASIC_CHAR:
1411         case TYPE_BASIC_WCHAR:
1412         case TYPE_BASIC_HYPER:
1413             return TRUE;
1414         case TYPE_BASIC_FLOAT:
1415         case TYPE_BASIC_DOUBLE:
1416         case TYPE_BASIC_ERROR_STATUS_T:
1417         case TYPE_BASIC_HANDLE:
1418             return FALSE;
1419         }
1420         return FALSE;
1421     default:
1422         return FALSE;
1423     }
1424 }
1425 
1426 static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
1427 {
1428   type_t *ptrchain_type;
1429   if (!ptrchain)
1430     return type;
1431   for (ptrchain_type = ptrchain; type_pointer_get_ref(ptrchain_type); ptrchain_type = type_pointer_get_ref(ptrchain_type))
1432     ;
1433   assert(ptrchain_type->type_type == TYPE_POINTER);
1434   ptrchain_type->details.pointer.ref = type;
1435   return ptrchain;
1436 }
1437 
1438 static warning_list_t *append_warning(warning_list_t *list, int num)
1439 {
1440     warning_t *entry;
1441 
1442     if(!list)
1443     {
1444         list = xmalloc( sizeof(*list) );
1445         list_init( list );
1446     }
1447     entry = xmalloc( sizeof(*entry) );
1448     entry->num = num;
1449     list_add_tail( list, &entry->entry );
1450     return list;
1451 }
1452 
1453 static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
1454                        int top)
1455 {
1456   var_t *v = decl->var;
1457   expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS);
1458   expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS);
1459   int sizeless;
1460   expr_t *dim;
1461   type_t **ptype;
1462   array_dims_t *arr = decl ? decl->array : NULL;
1463   type_t *func_type = decl ? decl->func_type : NULL;
1464   type_t *type = decl_spec->type;
1465 
1466   if (is_attr(type->attrs, ATTR_INLINE))
1467   {
1468     if (!func_type)
1469       error_loc("inline attribute applied to non-function type\n");
1470     else
1471     {
1472       type_t *t;
1473       /* move inline attribute from return type node to function node */
1474       for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
1475         ;
1476       t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
1477     }
1478   }
1479 
1480   /* add type onto the end of the pointers in pident->type */
1481   v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
1482   v->stgclass = decl_spec->stgclass;
1483   v->attrs = attrs;
1484 
1485   /* check for pointer attribute being applied to non-pointer, non-array
1486    * type */
1487   if (!arr)
1488   {
1489     int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
1490     const type_t *ptr = NULL;
1491     /* pointer attributes on the left side of the type belong to the function
1492      * pointer, if one is being declared */
1493     type_t **pt = func_type ? &func_type : &v->type;
1494     for (ptr = *pt; ptr && !ptr_attr; )
1495     {
1496       ptr_attr = get_attrv(ptr->attrs, ATTR_POINTERTYPE);
1497       if (!ptr_attr && type_is_alias(ptr))
1498         ptr = type_alias_get_aliasee(ptr);
1499       else
1500         break;
1501     }
1502     if (is_ptr(ptr))
1503     {
1504       if (ptr_attr && ptr_attr != RPC_FC_UP &&
1505           type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
1506           warning_loc_info(&v->loc_info,
1507                            "%s: pointer attribute applied to interface "
1508                            "pointer type has no effect\n", v->name);
1509       if (!ptr_attr && top && (*pt)->details.pointer.def_fc != RPC_FC_RP)
1510       {
1511         /* FIXME: this is a horrible hack to cope with the issue that we
1512          * store an offset to the typeformat string in the type object, but
1513          * two typeformat strings may be written depending on whether the
1514          * pointer is a toplevel parameter or not */
1515         *pt = duptype(*pt, 1);
1516       }
1517     }
1518     else if (ptr_attr)
1519        error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
1520   }
1521 
1522   if (is_attr(v->attrs, ATTR_STRING))
1523   {
1524     type_t *t = type;
1525 
1526     if (!is_ptr(v->type) && !arr)
1527       error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
1528                 v->name);
1529 
1530     while (is_ptr(t))
1531       t = type_pointer_get_ref(t);
1532 
1533     if (type_get_type(t) != TYPE_BASIC &&
1534         (get_basic_fc(t) != RPC_FC_CHAR &&
1535          get_basic_fc(t) != RPC_FC_BYTE &&
1536          get_basic_fc(t) != RPC_FC_WCHAR))
1537     {
1538       error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n",
1539                 v->name);
1540     }
1541   }
1542 
1543   if (is_attr(v->attrs, ATTR_V1ENUM))
1544   {
1545     if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
1546       error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
1547   }
1548 
1549   if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type))
1550     error_loc("'%s': [range] attribute applied to non-integer type\n",
1551               v->name);
1552 
1553   ptype = &v->type;
1554   sizeless = FALSE;
1555   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
1556   {
1557     if (sizeless)
1558       error_loc("%s: only the first array dimension can be unspecified\n", v->name);
1559 
1560     if (dim->is_const)
1561     {
1562       if (dim->cval <= 0)
1563         error_loc("%s: array dimension must be positive\n", v->name);
1564 
1565       /* FIXME: should use a type_memsize that allows us to pass in a pointer size */
1566       if (0)
1567       {
1568         unsigned int size = type_memsize(v->type);
1569 
1570         if (0xffffffffu / size < dim->cval)
1571           error_loc("%s: total array size is too large\n", v->name);
1572       }
1573     }
1574     else
1575       sizeless = TRUE;
1576 
1577     *ptype = type_new_array(NULL, *ptype, FALSE,
1578                             dim->is_const ? dim->cval : 0,
1579                             dim->is_const ? NULL : dim, NULL,
1580                             pointer_default);
1581   }
1582 
1583   ptype = &v->type;
1584   if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
1585   {
1586     if (dim->type != EXPR_VOID)
1587     {
1588       if (is_array(*ptype))
1589       {
1590         if (!type_array_get_conformance(*ptype) ||
1591             type_array_get_conformance(*ptype)->type != EXPR_VOID)
1592           error_loc("%s: cannot specify size_is for an already sized array\n", v->name);
1593         else
1594           *ptype = type_new_array((*ptype)->name,
1595                                   type_array_get_element(*ptype), FALSE,
1596                                   0, dim, NULL, 0);
1597       }
1598       else if (is_ptr(*ptype))
1599         *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
1600                                 0, dim, NULL, pointer_default);
1601       else
1602         error_loc("%s: size_is attribute applied to illegal type\n", v->name);
1603     }
1604 
1605     if (is_ptr(*ptype))
1606       ptype = &(*ptype)->details.pointer.ref;
1607     else if (is_array(*ptype))
1608       ptype = &(*ptype)->details.array.elem;
1609     else
1610       error_loc("%s: too many expressions in size_is attribute\n", v->name);
1611   }
1612 
1613   ptype = &v->type;
1614   if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
1615   {
1616     if (dim->type != EXPR_VOID)
1617     {
1618       if (is_array(*ptype))
1619       {
1620         *ptype = type_new_array((*ptype)->name,
1621                                 type_array_get_element(*ptype),
1622                                 type_array_is_decl_as_ptr(*ptype),
1623                                 type_array_get_dim(*ptype),
1624                                 type_array_get_conformance(*ptype),
1625                                 dim, type_array_get_ptr_default_fc(*ptype));
1626       }
1627       else
1628         error_loc("%s: length_is attribute applied to illegal type\n", v->name);
1629     }
1630 
1631     if (is_ptr(*ptype))
1632       ptype = &(*ptype)->details.pointer.ref;
1633     else if (is_array(*ptype))
1634       ptype = &(*ptype)->details.array.elem;
1635     else
1636       error_loc("%s: too many expressions in length_is attribute\n", v->name);
1637   }
1638 
1639   /* v->type is currently pointing to the type on the left-side of the
1640    * declaration, so we need to fix this up so that it is the return type of the
1641    * function and make v->type point to the function side of the declaration */
1642   if (func_type)
1643   {
1644     type_t *ft, *t;
1645     type_t *return_type = v->type;
1646     v->type = func_type;
1647     for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
1648       ;
1649     assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
1650     ft->details.function->retval = make_var(xstrdup("_RetVal"));
1651     ft->details.function->retval->type = return_type;
1652     /* move calling convention attribute, if present, from pointer nodes to
1653      * function node */
1654     for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
1655       ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
1656   }
1657   else
1658   {
1659     type_t *t;
1660     for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
1661       if (is_attr(t->attrs, ATTR_CALLCONV))
1662         error_loc("calling convention applied to non-function-pointer type\n");
1663   }
1664 
1665   if (decl->bits)
1666     v->type = type_new_bitfield(v->type, decl->bits);
1667 
1668   return v;
1669 }
1670 
1671 static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls)
1672 {
1673   declarator_t *decl, *next;
1674   var_list_t *var_list = NULL;
1675 
1676   LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
1677   {
1678     var_t *var = declare_var(attrs, decl_spec, decl, 0);
1679     var_list = append_var(var_list, var);
1680     free(decl);
1681   }
1682   free(decl_spec);
1683   return var_list;
1684 }
1685 
1686 static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface)
1687 {
1688     if (!iface) return list;
1689     if (!list)
1690     {
1691         list = xmalloc( sizeof(*list) );
1692         list_init( list );
1693     }
1694     list_add_tail( list, &iface->entry );
1695     return list;
1696 }
1697 
1698 static ifref_t *make_ifref(type_t *iface)
1699 {
1700   ifref_t *l = xmalloc(sizeof(ifref_t));
1701   l->iface = iface;
1702   l->attrs = NULL;
1703   return l;
1704 }
1705 
1706 var_list_t *append_var(var_list_t *list, var_t *var)
1707 {
1708     if (!var) return list;
1709     if (!list)
1710     {
1711         list = xmalloc( sizeof(*list) );
1712         list_init( list );
1713     }
1714     list_add_tail( list, &var->entry );
1715     return list;
1716 }
1717 
1718 static var_list_t *append_var_list(var_list_t *list, var_list_t *vars)
1719 {
1720     if (!vars) return list;
1721     if (!list)
1722     {
1723         list = xmalloc( sizeof(*list) );
1724         list_init( list );
1725     }
1726     list_move_tail( list, vars );
1727     return list;
1728 }
1729 
1730 var_t *make_var(char *name)
1731 {
1732   var_t *v = xmalloc(sizeof(var_t));
1733   v->name = name;
1734   v->type = NULL;
1735   v->attrs = NULL;
1736   v->eval = NULL;
1737   v->stgclass = STG_NONE;
1738   init_loc_info(&v->loc_info);
1739   return v;
1740 }
1741 
1742 static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *d)
1743 {
1744   if (!d) return list;
1745   if (!list) {
1746     list = xmalloc(sizeof(*list));
1747     list_init(list);
1748   }
1749   list_add_tail(list, &d->entry);
1750   return list;
1751 }
1752 
1753 static declarator_t *make_declarator(var_t *var)
1754 {
1755   declarator_t *d = xmalloc(sizeof(*d));
1756   d->var = var ? var : make_var(NULL);
1757   d->type = NULL;
1758   d->func_type = NULL;
1759   d->array = NULL;
1760   d->bits = NULL;
1761   return d;
1762 }
1763 
1764 static type_t *make_safearray(type_t *type)
1765 {
1766   return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
1767                         NULL, NULL, RPC_FC_RP);
1768 }
1769 
1770 static typelib_t *make_library(const char *name, const attr_list_t *attrs)
1771 {
1772     typelib_t *typelib = xmalloc(sizeof(*typelib));
1773     typelib->name = xstrdup(name);
1774     typelib->attrs = attrs;
1775     list_init( &typelib->importlibs );
1776     return typelib;
1777 }
1778 
1779 static int hash_ident(const char *name)
1780 {
1781   const char *p = name;
1782   int sum = 0;
1783   /* a simple sum hash is probably good enough */
1784   while (*p) {
1785     sum += *p;
1786     p++;
1787   }
1788   return sum & (HASHMAX-1);
1789 }
1790 
1791 /***** type repository *****/
1792 
1793 static struct namespace *find_sub_namespace(struct namespace *namespace, const char *name)
1794 {
1795   struct namespace *cur;
1796 
1797   LIST_FOR_EACH_ENTRY(cur, &namespace->children, struct namespace, entry) {
1798     if(!strcmp(cur->name, name))
1799       return cur;
1800   }
1801 
1802   return NULL;
1803 }
1804 
1805 static void push_namespace(const char *name)
1806 {
1807   struct namespace *namespace;
1808 
1809   namespace = find_sub_namespace(current_namespace, name);
1810   if(!namespace) {
1811     namespace = xmalloc(sizeof(*namespace));
1812     namespace->name = xstrdup(name);
1813     namespace->parent = current_namespace;
1814     list_add_tail(&current_namespace->children, &namespace->entry);
1815     list_init(&namespace->children);
1816     memset(namespace->type_hash, 0, sizeof(namespace->type_hash));
1817   }
1818 
1819   current_namespace = namespace;
1820 }
1821 
1822 static void pop_namespace(const char *name)
1823 {
1824   assert(!strcmp(current_namespace->name, name) && current_namespace->parent);
1825   current_namespace = current_namespace->parent;
1826 }
1827 
1828 struct rtype {
1829   const char *name;
1830   type_t *type;
1831   int t;
1832   struct rtype *next;
1833 };
1834 
1835 type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, int t)
1836 {
1837   struct rtype *nt;
1838   int hash;
1839   if (!name) {
1840     error_loc("registering named type without name\n");
1841     return type;
1842   }
1843   if (!namespace)
1844     namespace = &global_namespace;
1845   hash = hash_ident(name);
1846   nt = xmalloc(sizeof(struct rtype));
1847   nt->name = name;
1848   if (is_global_namespace(namespace))
1849     type->c_name = name;
1850   else
1851     type->c_name = format_namespace(namespace, "__x_", "_C", name);
1852   nt->type = type;
1853   nt->t = t;
1854   nt->next = namespace->type_hash[hash];
1855   namespace->type_hash[hash] = nt;
1856   if ((t == tsSTRUCT || t == tsUNION))
1857     fix_incomplete_types(type);
1858   return type;
1859 }
1860 
1861 static int is_incomplete(const type_t *t)
1862 {
1863   return !t->defined &&
1864     (type_get_type_detect_alias(t) == TYPE_STRUCT ||
1865      type_get_type_detect_alias(t) == TYPE_UNION ||
1866      type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
1867 }
1868 
1869 void add_incomplete(type_t *t)
1870 {
1871   struct typenode *tn = xmalloc(sizeof *tn);
1872   tn->type = t;
1873   list_add_tail(&incomplete_types, &tn->entry);
1874 }
1875 
1876 static void fix_type(type_t *t)
1877 {
1878   if (type_is_alias(t) && is_incomplete(t)) {
1879     type_t *ot = type_alias_get_aliasee(t);
1880     fix_type(ot);
1881     if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
1882         type_get_type_detect_alias(ot) == TYPE_UNION ||
1883         type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
1884       t->details.structure = ot->details.structure;
1885     t->defined = ot->defined;
1886   }
1887 }
1888 
1889 static void fix_incomplete(void)
1890 {
1891   struct typenode *tn, *next;
1892 
1893   LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) {
1894     fix_type(tn->type);
1895     list_remove(&tn->entry);
1896     free(tn);
1897   }
1898 }
1899 
1900 static void fix_incomplete_types(type_t *complete_type)
1901 {
1902   struct typenode *tn, *next;
1903 
1904   LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry)
1905   {
1906     if (type_is_equal(complete_type, tn->type))
1907     {
1908       tn->type->details.structure = complete_type->details.structure;
1909       list_remove(&tn->entry);
1910       free(tn);
1911     }
1912   }
1913 }
1914 
1915 static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs)
1916 {
1917   const declarator_t *decl;
1918   type_t *type = decl_spec->type;
1919 
1920   if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC))
1921     attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
1922 
1923   /* We must generate names for tagless enum, struct or union.
1924      Typedef-ing a tagless enum, struct or union means we want the typedef
1925      to be included in a library hence the public attribute.  */
1926   if (type_get_type_detect_alias(type) == TYPE_ENUM ||
1927       type_get_type_detect_alias(type) == TYPE_STRUCT ||
1928       type_get_type_detect_alias(type) == TYPE_UNION ||
1929       type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
1930   {
1931     if (!type->name)
1932       type->name = gen_name();
1933 
1934     /* replace existing attributes when generating a typelib */
1935     if (do_typelib)
1936         type->attrs = attrs;
1937   }
1938 
1939 #ifdef __REACTOS__ /* r53187 / 5bf224e */
1940   /* Append the SWITCHTYPE attribute to a non-encapsulated union if it does not already have it.  */
1941   if (type_get_type_detect_alias(type) == TYPE_UNION &&
1942       is_attr(attrs, ATTR_SWITCHTYPE) &&
1943       !is_attr(type->attrs, ATTR_SWITCHTYPE))
1944     type->attrs = append_attr(type->attrs, make_attrp(ATTR_SWITCHTYPE, get_attrp(attrs, ATTR_SWITCHTYPE)));
1945 #endif
1946 
1947   LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry )
1948   {
1949 
1950     if (decl->var->name) {
1951       type_t *cur;
1952       var_t *name;
1953 
1954       cur = find_type(decl->var->name, current_namespace, 0);
1955 
1956       /*
1957        * MIDL allows shadowing types that are declared in imported files.
1958        * We don't throw an error in this case and instead add a new type
1959        * (which is earlier on the list in hash table, so it will be used
1960        * instead of shadowed type).
1961        *
1962        * FIXME: We may consider string separated type tables for each input
1963        *        for cleaner solution.
1964        */
1965       if (cur && input_name == cur->loc_info.input_name)
1966           error_loc("%s: redefinition error; original definition was at %s:%d\n",
1967                     cur->name, cur->loc_info.input_name,
1968                     cur->loc_info.line_number);
1969 
1970       name = declare_var(attrs, decl_spec, decl, 0);
1971       cur = type_new_alias(name->type, name->name);
1972       cur->attrs = attrs;
1973 
1974       if (is_incomplete(cur))
1975         add_incomplete(cur);
1976       reg_type(cur, cur->name, current_namespace, 0);
1977     }
1978   }
1979   return type;
1980 }
1981 
1982 type_t *find_type(const char *name, struct namespace *namespace, int t)
1983 {
1984   struct rtype *cur;
1985 
1986   if(namespace && namespace != &global_namespace) {
1987     for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
1988       if(cur->t == t && !strcmp(cur->name, name))
1989         return cur->type;
1990     }
1991   }
1992   for(cur = global_namespace.type_hash[hash_ident(name)]; cur; cur = cur->next) {
1993     if(cur->t == t && !strcmp(cur->name, name))
1994       return cur->type;
1995   }
1996   return NULL;
1997 }
1998 
1999 static type_t *find_type_or_error(const char *name, int t)
2000 {
2001   type_t *type = find_type(name, NULL, t);
2002   if (!type) {
2003     error_loc("type '%s' not found\n", name);
2004     return NULL;
2005   }
2006   return type;
2007 }
2008 
2009 static type_t *find_type_or_error2(char *name, int t)
2010 {
2011   type_t *tp = find_type_or_error(name, t);
2012   free(name);
2013   return tp;
2014 }
2015 
2016 int is_type(const char *name)
2017 {
2018   return find_type(name, current_namespace, 0) != NULL;
2019 }
2020 
2021 type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t)
2022 {
2023   type_t *tp;
2024   if (!namespace)
2025     namespace = &global_namespace;
2026   if (name) {
2027     tp = find_type(name, namespace, t);
2028     if (tp) {
2029       free(name);
2030       return tp;
2031     }
2032   }
2033   tp = make_type(type);
2034   tp->name = name;
2035   tp->namespace = namespace;
2036   if (!name) return tp;
2037   return reg_type(tp, name, namespace, t);
2038 }
2039 
2040 /***** constant repository *****/
2041 
2042 struct rconst {
2043   char *name;
2044   var_t *var;
2045   struct rconst *next;
2046 };
2047 
2048 struct rconst *const_hash[HASHMAX];
2049 
2050 static var_t *reg_const(var_t *var)
2051 {
2052   struct rconst *nc;
2053   int hash;
2054   if (!var->name) {
2055     error_loc("registering constant without name\n");
2056     return var;
2057   }
2058   hash = hash_ident(var->name);
2059   nc = xmalloc(sizeof(struct rconst));
2060   nc->name = var->name;
2061   nc->var = var;
2062   nc->next = const_hash[hash];
2063   const_hash[hash] = nc;
2064   return var;
2065 }
2066 
2067 var_t *find_const(const char *name, int f)
2068 {
2069   struct rconst *cur = const_hash[hash_ident(name)];
2070   while (cur && strcmp(cur->name, name))
2071     cur = cur->next;
2072   if (!cur) {
2073     if (f) error_loc("constant '%s' not found\n", name);
2074     return NULL;
2075   }
2076   return cur->var;
2077 }
2078 
2079 static char *gen_name(void)
2080 {
2081   static const char format[] = "__WIDL_%s_generated_name_%08lX";
2082   static unsigned long n = 0;
2083   static const char *file_id;
2084   static size_t size;
2085   char *name;
2086 
2087   if (! file_id)
2088   {
2089     char *dst = dup_basename(input_idl_name, ".idl");
2090     file_id = dst;
2091 
2092     for (; *dst; ++dst)
2093       if (! isalnum((unsigned char) *dst))
2094         *dst = '_';
2095 
2096     size = sizeof format - 7 + strlen(file_id) + 8;
2097   }
2098 
2099   name = xmalloc(size);
2100   sprintf(name, format, file_id, n++);
2101   return name;
2102 }
2103 
2104 struct allowed_attr
2105 {
2106     unsigned int dce_compatible : 1;
2107     unsigned int acf : 1;
2108     unsigned int on_interface : 1;
2109     unsigned int on_function : 1;
2110     unsigned int on_arg : 1;
2111     unsigned int on_type : 1;
2112     unsigned int on_enum : 1;
2113     unsigned int on_struct : 2;
2114     unsigned int on_union : 1;
2115     unsigned int on_field : 1;
2116     unsigned int on_library : 1;
2117     unsigned int on_dispinterface : 1;
2118     unsigned int on_module : 1;
2119     unsigned int on_coclass : 1;
2120     const char *display_name;
2121 };
2122 
2123 struct allowed_attr allowed_attr[] =
2124 {
2125     /* attr                        { D ACF I Fn ARG T En St Un Fi  L  DI M  C  <display name> } */
2126     /* ATTR_AGGREGATABLE */        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "aggregatable" },
2127     /* ATTR_ANNOTATION */          { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
2128     /* ATTR_APPOBJECT */           { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "appobject" },
2129     /* ATTR_ASYNC */               { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "async" },
2130     /* ATTR_ASYNCUUID */           { 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, "async_uuid" },
2131     /* ATTR_AUTO_HANDLE */         { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "auto_handle" },
2132     /* ATTR_BINDABLE */            { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "bindable" },
2133     /* ATTR_BROADCAST */           { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
2134     /* ATTR_CALLAS */              { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "call_as" },
2135     /* ATTR_CALLCONV */            { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
2136     /* ATTR_CASE */                { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
2137     /* ATTR_CODE */                { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
2138     /* ATTR_COMMSTATUS */          { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
2139     /* ATTR_CONST */               { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
2140     /* ATTR_CONTEXTHANDLE */       { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
2141     /* ATTR_CONTROL */             { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
2142     /* ATTR_DECODE */              { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
2143     /* ATTR_DEFAULT */             { 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, "default" },
2144     /* ATTR_DEFAULTBIND */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultbind" },
2145     /* ATTR_DEFAULTCOLLELEM */     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
2146     /* ATTR_DEFAULTVALUE */        { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
2147     /* ATTR_DEFAULTVTABLE */       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" },
2148  /* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
2149     /* ATTR_DISPINTERFACE */       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
2150     /* ATTR_DISPLAYBIND */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
2151     /* ATTR_DLLNAME */             { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" },
2152     /* ATTR_DUAL */                { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
2153     /* ATTR_ENABLEALLOCATE */      { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "enable_allocate" },
2154     /* ATTR_ENCODE */              { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "encode" },
2155     /* ATTR_ENDPOINT */            { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
2156     /* ATTR_ENTRY */               { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "entry" },
2157     /* ATTR_EXPLICIT_HANDLE */     { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
2158     /* ATTR_FAULTSTATUS */         { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "fault_status" },
2159     /* ATTR_FORCEALLOCATE */       { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "force_allocate" },
2160     /* ATTR_HANDLE */              { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "handle" },
2161     /* ATTR_HELPCONTEXT */         { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, "helpcontext" },
2162     /* ATTR_HELPFILE */            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpfile" },
2163     /* ATTR_HELPSTRING */          { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, "helpstring" },
2164     /* ATTR_HELPSTRINGCONTEXT */   { 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, "helpstringcontext" },
2165     /* ATTR_HELPSTRINGDLL */       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "helpstringdll" },
2166     /* ATTR_HIDDEN */              { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, "hidden" },
2167     /* ATTR_ID */                  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, "id" },
2168     /* ATTR_IDEMPOTENT */          { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "idempotent" },
2169     /* ATTR_IGNORE */              { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "ignore" },
2170     /* ATTR_IIDIS */               { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "iid_is" },
2171     /* ATTR_IMMEDIATEBIND */       { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
2172     /* ATTR_IMPLICIT_HANDLE */     { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
2173     /* ATTR_IN */                  { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
2174     /* ATTR_INLINE */              { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
2175     /* ATTR_INPUTSYNC */           { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
2176     /* ATTR_LENGTHIS */            { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
2177     /* ATTR_LIBLCID */             { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
2178     /* ATTR_LICENSED */            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "licensed" },
2179     /* ATTR_LOCAL */               { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "local" },
2180     /* ATTR_MAYBE */               { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "maybe" },
2181     /* ATTR_MESSAGE */             { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "message" },
2182     /* ATTR_NOCODE */              { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nocode" },
2183     /* ATTR_NONBROWSABLE */        { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
2184     /* ATTR_NONCREATABLE */        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" },
2185     /* ATTR_NONEXTENSIBLE */       { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "nonextensible" },
2186     /* ATTR_NOTIFY */              { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify" },
2187     /* ATTR_NOTIFYFLAG */          { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "notify_flag" },
2188     /* ATTR_OBJECT */              { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "object" },
2189     /* ATTR_ODL */                 { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "odl" },
2190     /* ATTR_OLEAUTOMATION */       { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "oleautomation" },
2191     /* ATTR_OPTIMIZE */            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optimize" },
2192     /* ATTR_OPTIONAL */            { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "optional" },
2193     /* ATTR_OUT */                 { 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "out" },
2194     /* ATTR_PARAMLCID */           { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "lcid" },
2195     /* ATTR_PARTIALIGNORE */       { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "partial_ignore" },
2196     /* ATTR_POINTERDEFAULT */      { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "pointer_default" },
2197     /* ATTR_POINTERTYPE */         { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, "ref, unique or ptr" },
2198     /* ATTR_PROGID */              { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "progid" },
2199     /* ATTR_PROPGET */             { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propget" },
2200     /* ATTR_PROPPUT */             { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propput" },
2201     /* ATTR_PROPPUTREF */          { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "propputref" },
2202     /* ATTR_PROXY */               { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "proxy" },
2203     /* ATTR_PUBLIC */              { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "public" },
2204     /* ATTR_RANGE */               { 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, "range" },
2205     /* ATTR_READONLY */            { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "readonly" },
2206     /* ATTR_REPRESENTAS */         { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "represent_as" },
2207     /* ATTR_REQUESTEDIT */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "requestedit" },
2208     /* ATTR_RESTRICTED */          { 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, "restricted" },
2209     /* ATTR_RETVAL */              { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
2210     /* ATTR_SIZEIS */              { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "size_is" },
2211     /* ATTR_SOURCE */              { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "source" },
2212     /* ATTR_STRICTCONTEXTHANDLE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "strict_context_handle" },
2213     /* ATTR_STRING */              { 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, "string" },
2214     /* ATTR_SWITCHIS */            { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "switch_is" },
2215     /* ATTR_SWITCHTYPE */          { 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, "switch_type" },
2216     /* ATTR_THREADING */           { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "threading" },
2217     /* ATTR_TRANSMITAS */          { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "transmit_as" },
2218     /* ATTR_UIDEFAULT */           { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "uidefault" },
2219     /* ATTR_USESGETLASTERROR */    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "usesgetlasterror" },
2220     /* ATTR_USERMARSHAL */         { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "user_marshal" },
2221     /* ATTR_UUID */                { 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, "uuid" },
2222     /* ATTR_V1ENUM */              { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, "v1_enum" },
2223     /* ATTR_VARARG */              { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "vararg" },
2224     /* ATTR_VERSION */             { 1, 0, 1, 0, 0, 1, 1, 2, 0, 0, 1, 0, 0, 1, "version" },
2225     /* ATTR_VIPROGID */            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "vi_progid" },
2226     /* ATTR_WIREMARSHAL */         { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "wire_marshal" },
2227 };
2228 
2229 const char *get_attr_display_name(enum attr_type type)
2230 {
2231     return allowed_attr[type].display_name;
2232 }
2233 
2234 static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
2235 {
2236   const attr_t *attr;
2237   if (!attrs) return attrs;
2238   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2239   {
2240     if (!allowed_attr[attr->type].on_interface)
2241       error_loc("inapplicable attribute %s for interface %s\n",
2242                 allowed_attr[attr->type].display_name, name);
2243     if (attr->type == ATTR_IMPLICIT_HANDLE)
2244     {
2245         const var_t *var = attr->u.pval;
2246         if (type_get_type( var->type) == TYPE_BASIC &&
2247             type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
2248             continue;
2249         if (is_aliaschain_attr( var->type, ATTR_HANDLE ))
2250             continue;
2251       error_loc("attribute %s requires a handle type in interface %s\n",
2252                 allowed_attr[attr->type].display_name, name);
2253     }
2254   }
2255   return attrs;
2256 }
2257 
2258 static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs)
2259 {
2260   const attr_t *attr;
2261   if (!attrs) return attrs;
2262   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2263   {
2264     if (!allowed_attr[attr->type].on_function)
2265       error_loc("inapplicable attribute %s for function %s\n",
2266                 allowed_attr[attr->type].display_name, name);
2267   }
2268   return attrs;
2269 }
2270 
2271 static void check_arg_attrs(const var_t *arg)
2272 {
2273   const attr_t *attr;
2274 
2275   if (arg->attrs)
2276   {
2277     LIST_FOR_EACH_ENTRY(attr, arg->attrs, const attr_t, entry)
2278     {
2279       if (!allowed_attr[attr->type].on_arg)
2280         error_loc("inapplicable attribute %s for argument %s\n",
2281                   allowed_attr[attr->type].display_name, arg->name);
2282     }
2283   }
2284 }
2285 
2286 static attr_list_t *check_typedef_attrs(attr_list_t *attrs)
2287 {
2288   const attr_t *attr;
2289   if (!attrs) return attrs;
2290   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2291   {
2292     if (!allowed_attr[attr->type].on_type)
2293       error_loc("inapplicable attribute %s for typedef\n",
2294                 allowed_attr[attr->type].display_name);
2295   }
2296   return attrs;
2297 }
2298 
2299 static attr_list_t *check_enum_attrs(attr_list_t *attrs)
2300 {
2301   const attr_t *attr;
2302   if (!attrs) return attrs;
2303   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2304   {
2305     if (!allowed_attr[attr->type].on_enum)
2306       error_loc("inapplicable attribute %s for enum\n",
2307                 allowed_attr[attr->type].display_name);
2308   }
2309   return attrs;
2310 }
2311 
2312 static attr_list_t *check_struct_attrs(attr_list_t *attrs)
2313 {
2314   int mask = winrt_mode ? 3 : 1;
2315   const attr_t *attr;
2316   if (!attrs) return attrs;
2317   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2318   {
2319     if (!(allowed_attr[attr->type].on_struct & mask))
2320       error_loc("inapplicable attribute %s for struct\n",
2321                 allowed_attr[attr->type].display_name);
2322   }
2323   return attrs;
2324 }
2325 
2326 static attr_list_t *check_union_attrs(attr_list_t *attrs)
2327 {
2328   const attr_t *attr;
2329   if (!attrs) return attrs;
2330   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2331   {
2332     if (!allowed_attr[attr->type].on_union)
2333       error_loc("inapplicable attribute %s for union\n",
2334                 allowed_attr[attr->type].display_name);
2335   }
2336   return attrs;
2337 }
2338 
2339 static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs)
2340 {
2341   const attr_t *attr;
2342   if (!attrs) return attrs;
2343   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2344   {
2345     if (!allowed_attr[attr->type].on_field)
2346       error_loc("inapplicable attribute %s for field %s\n",
2347                 allowed_attr[attr->type].display_name, name);
2348   }
2349   return attrs;
2350 }
2351 
2352 static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs)
2353 {
2354   const attr_t *attr;
2355   if (!attrs) return attrs;
2356   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2357   {
2358     if (!allowed_attr[attr->type].on_library)
2359       error_loc("inapplicable attribute %s for library %s\n",
2360                 allowed_attr[attr->type].display_name, name);
2361   }
2362   return attrs;
2363 }
2364 
2365 static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
2366 {
2367   const attr_t *attr;
2368   if (!attrs) return attrs;
2369   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2370   {
2371     if (!allowed_attr[attr->type].on_dispinterface)
2372       error_loc("inapplicable attribute %s for dispinterface %s\n",
2373                 allowed_attr[attr->type].display_name, name);
2374   }
2375   return attrs;
2376 }
2377 
2378 static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs)
2379 {
2380   const attr_t *attr;
2381   if (!attrs) return attrs;
2382   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2383   {
2384     if (!allowed_attr[attr->type].on_module)
2385       error_loc("inapplicable attribute %s for module %s\n",
2386                 allowed_attr[attr->type].display_name, name);
2387   }
2388   return attrs;
2389 }
2390 
2391 static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
2392 {
2393   const attr_t *attr;
2394   if (!attrs) return attrs;
2395   LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry)
2396   {
2397     if (!allowed_attr[attr->type].on_coclass)
2398       error_loc("inapplicable attribute %s for coclass %s\n",
2399                 allowed_attr[attr->type].display_name, name);
2400   }
2401   return attrs;
2402 }
2403 
2404 static int is_allowed_conf_type(const type_t *type)
2405 {
2406     switch (type_get_type(type))
2407     {
2408     case TYPE_ENUM:
2409         return TRUE;
2410     case TYPE_BASIC:
2411         switch (type_basic_get_type(type))
2412         {
2413         case TYPE_BASIC_INT8:
2414         case TYPE_BASIC_INT16:
2415         case TYPE_BASIC_INT32:
2416         case TYPE_BASIC_INT64:
2417         case TYPE_BASIC_INT:
2418         case TYPE_BASIC_CHAR:
2419         case TYPE_BASIC_HYPER:
2420         case TYPE_BASIC_BYTE:
2421         case TYPE_BASIC_WCHAR:
2422             return TRUE;
2423         default:
2424             return FALSE;
2425         }
2426     case TYPE_ALIAS:
2427         /* shouldn't get here because of type_get_type call above */
2428         assert(0);
2429         /* fall through */
2430     case TYPE_STRUCT:
2431     case TYPE_UNION:
2432     case TYPE_ENCAPSULATED_UNION:
2433     case TYPE_ARRAY:
2434     case TYPE_POINTER:
2435     case TYPE_VOID:
2436     case TYPE_MODULE:
2437     case TYPE_COCLASS:
2438     case TYPE_FUNCTION:
2439     case TYPE_INTERFACE:
2440     case TYPE_BITFIELD:
2441         return FALSE;
2442     }
2443     return FALSE;
2444 }
2445 
2446 static int is_ptr_guid_type(const type_t *type)
2447 {
2448     /* first, make sure it is a pointer to something */
2449     if (!is_ptr(type)) return FALSE;
2450 
2451     /* second, make sure it is a pointer to something of size sizeof(GUID),
2452      * i.e. 16 bytes */
2453     return (type_memsize(type_pointer_get_ref(type)) == 16);
2454 }
2455 
2456 static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
2457 {
2458     expr_t *dim;
2459     struct expr_loc expr_loc;
2460     expr_loc.v = arg;
2461     expr_loc.attr = attr_name;
2462     if (expr_list) LIST_FOR_EACH_ENTRY(dim, expr_list, expr_t, entry)
2463     {
2464         if (dim->type != EXPR_VOID)
2465         {
2466             const type_t *expr_type = expr_resolve_type(&expr_loc, container_type, dim);
2467             if (!is_allowed_conf_type(expr_type))
2468                 error_loc_info(&arg->loc_info, "expression must resolve to integral type <= 32bits for attribute %s\n",
2469                                attr_name);
2470         }
2471     }
2472 }
2473 
2474 static void check_remoting_fields(const var_t *var, type_t *type);
2475 
2476 /* checks that properties common to fields and arguments are consistent */
2477 static void check_field_common(const type_t *container_type,
2478                                const char *container_name, const var_t *arg)
2479 {
2480     type_t *type = arg->type;
2481     int more_to_do;
2482     const char *container_type_name;
2483     const char *var_type;
2484 
2485     switch (type_get_type(container_type))
2486     {
2487     case TYPE_STRUCT:
2488         container_type_name = "struct";
2489         var_type = "field";
2490         break;
2491     case TYPE_UNION:
2492         container_type_name = "union";
2493         var_type = "arm";
2494         break;
2495     case TYPE_ENCAPSULATED_UNION:
2496         container_type_name = "encapsulated union";
2497         var_type = "arm";
2498         break;
2499     case TYPE_FUNCTION:
2500         container_type_name = "function";
2501         var_type = "parameter";
2502         break;
2503     default:
2504         /* should be no other container types */
2505         assert(0);
2506         return;
2507     }
2508 
2509     if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
2510         (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
2511         error_loc_info(&arg->loc_info,
2512                        "string and length_is specified for argument %s are mutually exclusive attributes\n",
2513                        arg->name);
2514 
2515     if (is_attr(arg->attrs, ATTR_SIZEIS))
2516     {
2517         expr_list_t *size_is_exprs = get_attrp(arg->attrs, ATTR_SIZEIS);
2518         check_conformance_expr_list("size_is", arg, container_type, size_is_exprs);
2519     }
2520     if (is_attr(arg->attrs, ATTR_LENGTHIS))
2521     {
2522         expr_list_t *length_is_exprs = get_attrp(arg->attrs, ATTR_LENGTHIS);
2523         check_conformance_expr_list("length_is", arg, container_type, length_is_exprs);
2524     }
2525     if (is_attr(arg->attrs, ATTR_IIDIS))
2526     {
2527         struct expr_loc expr_loc;
2528         expr_t *expr = get_attrp(arg->attrs, ATTR_IIDIS);
2529         if (expr->type != EXPR_VOID)
2530         {
2531             const type_t *expr_type;
2532             expr_loc.v = arg;
2533             expr_loc.attr = "iid_is";
2534             expr_type = expr_resolve_type(&expr_loc, container_type, expr);
2535             if (!expr_type || !is_ptr_guid_type(expr_type))
2536                 error_loc_info(&arg->loc_info, "expression must resolve to pointer to GUID type for attribute iid_is\n");
2537         }
2538     }
2539     if (is_attr(arg->attrs, ATTR_SWITCHIS))
2540     {
2541         struct expr_loc expr_loc;
2542         expr_t *expr = get_attrp(arg->attrs, ATTR_SWITCHIS);
2543         if (expr->type != EXPR_VOID)
2544         {
2545             const type_t *expr_type;
2546             expr_loc.v = arg;
2547             expr_loc.attr = "switch_is";
2548             expr_type = expr_resolve_type(&expr_loc, container_type, expr);
2549             if (!expr_type || !is_allowed_conf_type(expr_type))
2550                 error_loc_info(&arg->loc_info, "expression must resolve to integral type <= 32bits for attribute %s\n",
2551                                expr_loc.attr);
2552         }
2553     }
2554 
2555     do
2556     {
2557         more_to_do = FALSE;
2558 
2559         switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
2560         {
2561         case TGT_STRUCT:
2562         case TGT_UNION:
2563             check_remoting_fields(arg, type);
2564             break;
2565         case TGT_INVALID:
2566         {
2567             const char *reason = "is invalid";
2568             switch (type_get_type(type))
2569             {
2570             case TYPE_VOID:
2571                 reason = "cannot derive from void *";
2572                 break;
2573             case TYPE_FUNCTION:
2574                 reason = "cannot be a function pointer";
2575                 break;
2576             case TYPE_BITFIELD:
2577                 reason = "cannot be a bit-field";
2578                 break;
2579             case TYPE_COCLASS:
2580                 reason = "cannot be a class";
2581                 break;
2582             case TYPE_INTERFACE:
2583                 reason = "cannot be a non-pointer to an interface";
2584                 break;
2585             case TYPE_MODULE:
2586                 reason = "cannot be a module";
2587                 break;
2588             default:
2589                 break;
2590             }
2591             error_loc_info(&arg->loc_info, "%s \'%s\' of %s \'%s\' %s\n",
2592                            var_type, arg->name, container_type_name, container_name, reason);
2593             break;
2594         }
2595         case TGT_CTXT_HANDLE:
2596         case TGT_CTXT_HANDLE_POINTER:
2597             if (type_get_type(container_type) != TYPE_FUNCTION)
2598                 error_loc_info(&arg->loc_info,
2599                                "%s \'%s\' of %s \'%s\' cannot be a context handle\n",
2600                                var_type, arg->name, container_type_name,
2601                                container_name);
2602             break;
2603         case TGT_STRING:
2604         {
2605             const type_t *t = type;
2606             while (is_ptr(t))
2607                 t = type_pointer_get_ref(t);
2608             if (is_aliaschain_attr(t, ATTR_RANGE))
2609                 warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
2610             break;
2611         }
2612         case TGT_POINTER:
2613             type = type_pointer_get_ref(type);
2614             more_to_do = TRUE;
2615             break;
2616         case TGT_ARRAY:
2617             type = type_array_get_element(type);
2618             more_to_do = TRUE;
2619             break;
2620         case TGT_USER_TYPE:
2621         case TGT_IFACE_POINTER:
2622         case TGT_BASIC:
2623         case TGT_ENUM:
2624         case TGT_RANGE:
2625             /* nothing to do */
2626             break;
2627         }
2628     } while (more_to_do);
2629 }
2630 
2631 static void check_remoting_fields(const var_t *var, type_t *type)
2632 {
2633     const var_t *field;
2634     const var_list_t *fields = NULL;
2635 
2636     type = type_get_real_type(type);
2637 
2638     if (type->checked)
2639         return;
2640 
2641     type->checked = TRUE;
2642 
2643     if (type_get_type(type) == TYPE_STRUCT)
2644     {
2645         if (type_is_complete(type))
2646             fields = type_struct_get_fields(type);
2647         else
2648             error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
2649     }
2650     else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
2651         fields = type_union_get_cases(type);
2652 
2653     if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
2654         if (field->type) check_field_common(type, type->name, field);
2655 }
2656 
2657 /* checks that arguments for a function make sense for marshalling and unmarshalling */
2658 static void check_remoting_args(const var_t *func)
2659 {
2660     const char *funcname = func->name;
2661     const var_t *arg;
2662 
2663     if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
2664     {
2665         const type_t *type = arg->type;
2666 
2667         /* check that [out] parameters have enough pointer levels */
2668         if (is_attr(arg->attrs, ATTR_OUT))
2669         {
2670             switch (typegen_detect_type(type, arg->attrs, TDT_ALL_TYPES))
2671             {
2672             case TGT_BASIC:
2673             case TGT_ENUM:
2674             case TGT_RANGE:
2675             case TGT_STRUCT:
2676             case TGT_UNION:
2677             case TGT_CTXT_HANDLE:
2678             case TGT_USER_TYPE:
2679                 error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
2680                 break;
2681             case TGT_IFACE_POINTER:
2682                 error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
2683                 break;
2684             case TGT_STRING:
2685                 if (is_array(type))
2686                 {
2687                     /* needs conformance or fixed dimension */
2688                     if (type_array_has_conformance(type) &&
2689                         type_array_get_conformance(type)->type != EXPR_VOID) break;
2690                     if (!type_array_has_conformance(type) && type_array_get_dim(type)) break;
2691                 }
2692                 if (is_attr( arg->attrs, ATTR_IN )) break;
2693                 error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' cannot be an unsized string\n", arg->name, funcname);
2694                 break;
2695             case TGT_INVALID:
2696                 /* already error'd before we get here */
2697             case TGT_CTXT_HANDLE_POINTER:
2698             case TGT_POINTER:
2699             case TGT_ARRAY:
2700                 /* OK */
2701                 break;
2702             }
2703         }
2704 
2705         check_field_common(func->type, funcname, arg);
2706     }
2707 
2708     if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
2709     {
2710         var_t var;
2711         var = *func;
2712         var.type = type_function_get_rettype(func->type);
2713         var.name = xstrdup("return value");
2714         check_field_common(func->type, funcname, &var);
2715         free(var.name);
2716     }
2717 }
2718 
2719 static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
2720 {
2721     unsigned char explicit_fc, implicit_fc;
2722 
2723     /* check for a defined binding handle */
2724     if (!get_func_handle_var( iface, func, &explicit_fc, &implicit_fc ) || !explicit_fc)
2725     {
2726         /* no explicit handle specified so add
2727          * "[in] handle_t IDL_handle" as the first parameter to the
2728          * function */
2729         var_t *idl_handle = make_var(xstrdup("IDL_handle"));
2730         idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
2731         idl_handle->type = find_type_or_error("handle_t", 0);
2732         type_function_add_head_arg(func->type, idl_handle);
2733     }
2734 }
2735 
2736 static void check_functions(const type_t *iface, int is_inside_library)
2737 {
2738     const statement_t *stmt;
2739     if (is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE))
2740     {
2741         STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
2742         {
2743             var_t *func = stmt->u.var;
2744             add_explicit_handle_if_necessary(iface, func);
2745         }
2746     }
2747     if (!is_inside_library && !is_attr(iface->attrs, ATTR_LOCAL))
2748     {
2749         STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
2750         {
2751             const var_t *func = stmt->u.var;
2752             if (!is_attr(func->attrs, ATTR_LOCAL))
2753                 check_remoting_args(func);
2754         }
2755     }
2756 }
2757 
2758 static void check_statements(const statement_list_t *stmts, int is_inside_library)
2759 {
2760     const statement_t *stmt;
2761 
2762     if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
2763     {
2764         switch(stmt->type) {
2765         case STMT_LIBRARY:
2766             check_statements(stmt->u.lib->stmts, TRUE);
2767             break;
2768         case STMT_TYPE:
2769             switch(type_get_type(stmt->u.type)) {
2770             case TYPE_INTERFACE:
2771                 check_functions(stmt->u.type, is_inside_library);
2772                 break;
2773             case TYPE_COCLASS:
2774                 if(winrt_mode)
2775                     error_loc("coclass is not allowed in Windows Runtime mode\n");
2776                 break;
2777             default:
2778                 break;
2779             }
2780             break;
2781         default:
2782             break;
2783         }
2784     }
2785 }
2786 
2787 static void check_all_user_types(const statement_list_t *stmts)
2788 {
2789   const statement_t *stmt;
2790 
2791   if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
2792   {
2793     if (stmt->type == STMT_LIBRARY)
2794       check_all_user_types(stmt->u.lib->stmts);
2795     else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE &&
2796              !is_local(stmt->u.type->attrs))
2797     {
2798       const statement_t *stmt_func;
2799       STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
2800         const var_t *func = stmt_func->u.var;
2801         check_for_additional_prototype_types(func->type->details.function->args);
2802       }
2803     }
2804   }
2805 }
2806 
2807 int is_valid_uuid(const char *s)
2808 {
2809   int i;
2810 
2811   for (i = 0; i < 36; ++i)
2812     if (i == 8 || i == 13 || i == 18 || i == 23)
2813     {
2814       if (s[i] != '-')
2815         return FALSE;
2816     }
2817     else
2818       if (!isxdigit(s[i]))
2819         return FALSE;
2820 
2821   return s[i] == '\0';
2822 }
2823 
2824 static statement_t *make_statement(enum statement_type type)
2825 {
2826     statement_t *stmt = xmalloc(sizeof(*stmt));
2827     stmt->type = type;
2828     return stmt;
2829 }
2830 
2831 static statement_t *make_statement_type_decl(type_t *type)
2832 {
2833     statement_t *stmt = make_statement(STMT_TYPE);
2834     stmt->u.type = type;
2835     return stmt;
2836 }
2837 
2838 static statement_t *make_statement_reference(type_t *type)
2839 {
2840     statement_t *stmt = make_statement(STMT_TYPEREF);
2841     stmt->u.type = type;
2842     return stmt;
2843 }
2844 
2845 static statement_t *make_statement_declaration(var_t *var)
2846 {
2847     statement_t *stmt = make_statement(STMT_DECLARATION);
2848     stmt->u.var = var;
2849     if (var->stgclass == STG_EXTERN && var->eval)
2850         warning("'%s' initialised and declared extern\n", var->name);
2851     if (is_const_decl(var))
2852     {
2853         if (var->eval)
2854             reg_const(var);
2855     }
2856     else if (type_get_type(var->type) == TYPE_FUNCTION)
2857         check_function_attrs(var->name, var->attrs);
2858     else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER)
2859         error_loc("instantiation of data is illegal\n");
2860     return stmt;
2861 }
2862 
2863 static statement_t *make_statement_library(typelib_t *typelib)
2864 {
2865     statement_t *stmt = make_statement(STMT_LIBRARY);
2866     stmt->u.lib = typelib;
2867     return stmt;
2868 }
2869 
2870 static statement_t *make_statement_pragma(const char *str)
2871 {
2872     statement_t *stmt = make_statement(STMT_PRAGMA);
2873     stmt->u.str = str;
2874     return stmt;
2875 }
2876 
2877 static statement_t *make_statement_cppquote(const char *str)
2878 {
2879     statement_t *stmt = make_statement(STMT_CPPQUOTE);
2880     stmt->u.str = str;
2881     return stmt;
2882 }
2883 
2884 static statement_t *make_statement_importlib(const char *str)
2885 {
2886     statement_t *stmt = make_statement(STMT_IMPORTLIB);
2887     stmt->u.str = str;
2888     return stmt;
2889 }
2890 
2891 static statement_t *make_statement_import(const char *str)
2892 {
2893     statement_t *stmt = make_statement(STMT_IMPORT);
2894     stmt->u.str = str;
2895     return stmt;
2896 }
2897 
2898 static statement_t *make_statement_module(type_t *type)
2899 {
2900     statement_t *stmt = make_statement(STMT_MODULE);
2901     stmt->u.type = type;
2902     return stmt;
2903 }
2904 
2905 static statement_t *make_statement_typedef(declarator_list_t *decls)
2906 {
2907     declarator_t *decl, *next;
2908     statement_t *stmt;
2909     type_list_t **type_list;
2910 
2911     if (!decls) return NULL;
2912 
2913     stmt = make_statement(STMT_TYPEDEF);
2914     stmt->u.type_list = NULL;
2915     type_list = &stmt->u.type_list;
2916 
2917     LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
2918     {
2919         var_t *var = decl->var;
2920         type_t *type = find_type_or_error(var->name, 0);
2921         *type_list = xmalloc(sizeof(type_list_t));
2922         (*type_list)->type = type;
2923         (*type_list)->next = NULL;
2924 
2925         type_list = &(*type_list)->next;
2926         free(decl);
2927         free(var);
2928     }
2929 
2930     return stmt;
2931 }
2932 
2933 static statement_list_t *append_statements(statement_list_t *l1, statement_list_t *l2)
2934 {
2935     if (!l2) return l1;
2936     if (!l1 || l1 == l2) return l2;
2937     list_move_tail (l1, l2);
2938     return l1;
2939 }
2940 
2941 static attr_list_t *append_attribs(attr_list_t *l1, attr_list_t *l2)
2942 {
2943     if (!l2) return l1;
2944     if (!l1 || l1 == l2) return l2;
2945     list_move_tail (l1, l2);
2946     return l1;
2947 }
2948 
2949 static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt)
2950 {
2951     if (!stmt) return list;
2952     if (!list)
2953     {
2954         list = xmalloc( sizeof(*list) );
2955         list_init( list );
2956     }
2957     list_add_tail( list, &stmt->entry );
2958     return list;
2959 }
2960 
2961 void init_loc_info(loc_info_t *i)
2962 {
2963     i->input_name = input_name ? input_name : "stdin";
2964     i->line_number = line_number;
2965     i->near_text = parser_text;
2966 }
2967 
2968 static void check_def(const type_t *t)
2969 {
2970     if (t->defined)
2971         error_loc("%s: redefinition error; original definition was at %s:%d\n",
2972                   t->name, t->loc_info.input_name, t->loc_info.line_number);
2973 }
2974