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