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