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