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