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