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