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