/mingw-w64-v2.0.999/mingw/mingw-w64-tools/widl/src/parser.y
Happy | 2821 lines | 2538 code | 283 blank | 0 comment | 0 complexity | 4045a6d09d8bd6c05e756919cc0cd670 MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0, LGPL-3.0, Unlicense, GPL-2.0, LGPL-2.0, BSD-3-Clause, GPL-3.0
Large files files are truncated, but you can click here to view the full file
- %{
- /*
- * IDL Compiler
- *
- * Copyright 2002 Ove Kaaven
- * Copyright 2006-2008 Robert Shearman
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
- #include "config.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <assert.h>
- #include <ctype.h>
- #include <string.h>
- #include "widl.h"
- #include "utils.h"
- #include "parser.h"
- #include "header.h"
- #include "typelib.h"
- #include "typegen.h"
- #include "expr.h"
- #include "typetree.h"
- #if defined(YYBYACC)
- /* Berkeley yacc (byacc) doesn't seem to know about these */
- /* Some *BSD supplied versions do define these though */
- # ifndef YYEMPTY
- # define YYEMPTY (-1) /* Empty lookahead value of yychar */
- # endif
- # ifndef YYLEX
- # define YYLEX yylex()
- # endif
- #elif defined(YYBISON)
- /* Bison was used for original development */
- /* #define YYEMPTY -2 */
- /* #define YYLEX yylex() */
- #else
- /* No yacc we know yet */
- # if !defined(YYEMPTY) || !defined(YYLEX)
- # error Yacc version/type unknown. This version needs to be verified for settings of YYEMPTY and YYLEX.
- # elif defined(__GNUC__) /* gcc defines the #warning directive */
- # warning Yacc version/type unknown. It defines YYEMPTY and YYLEX, but is not tested
- /* #else we just take a chance that it works... */
- # endif
- #endif
- #define YYERROR_VERBOSE
- static unsigned char pointer_default = RPC_FC_UP;
- typedef struct list typelist_t;
- struct typenode {
- type_t *type;
- struct list entry;
- };
- struct _import_t
- {
- char *name;
- int import_performed;
- };
- typedef struct _decl_spec_t
- {
- type_t *type;
- attr_list_t *attrs;
- enum storage_class stgclass;
- } decl_spec_t;
- typelist_t incomplete_types = LIST_INIT(incomplete_types);
- static void fix_incomplete(void);
- static void fix_incomplete_types(type_t *complete_type);
- static str_list_t *append_str(str_list_t *list, char *str);
- static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
- static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
- 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);
- static attr_t *make_attr(enum attr_type type);
- static attr_t *make_attrv(enum attr_type type, unsigned int val);
- static attr_t *make_attrp(enum attr_type type, void *val);
- static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
- static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
- static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top);
- static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls);
- static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
- static ifref_t *make_ifref(type_t *iface);
- static var_list_t *append_var_list(var_list_t *list, var_list_t *vars);
- static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p);
- static declarator_t *make_declarator(var_t *var);
- static type_t *make_safearray(type_t *type);
- static typelib_t *make_library(const char *name, const attr_list_t *attrs);
- static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type);
- static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
- static type_t *find_type_or_error(const char *name, int t);
- static type_t *find_type_or_error2(char *name, int t);
- static var_t *reg_const(var_t *var);
- static char *gen_name(void);
- static void check_arg_attrs(const var_t *arg);
- static void check_statements(const statement_list_t *stmts, int is_inside_library);
- static void check_all_user_types(const statement_list_t *stmts);
- static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
- static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
- static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
- static attr_list_t *check_enum_attrs(attr_list_t *attrs);
- static attr_list_t *check_struct_attrs(attr_list_t *attrs);
- static attr_list_t *check_union_attrs(attr_list_t *attrs);
- static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
- static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
- static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
- static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
- static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
- const char *get_attr_display_name(enum attr_type type);
- static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
- static void check_def(const type_t *t);
- static statement_t *make_statement(enum statement_type type);
- static statement_t *make_statement_type_decl(type_t *type);
- static statement_t *make_statement_reference(type_t *type);
- static statement_t *make_statement_declaration(var_t *var);
- static statement_t *make_statement_library(typelib_t *typelib);
- static statement_t *make_statement_cppquote(const char *str);
- static statement_t *make_statement_importlib(const char *str);
- static statement_t *make_statement_module(type_t *type);
- static statement_t *make_statement_typedef(var_list_t *names);
- static statement_t *make_statement_import(const char *str);
- static statement_t *make_statement_typedef(var_list_t *names);
- static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
- %}
- %union {
- attr_t *attr;
- attr_list_t *attr_list;
- str_list_t *str_list;
- expr_t *expr;
- expr_list_t *expr_list;
- array_dims_t *array_dims;
- type_t *type;
- var_t *var;
- var_list_t *var_list;
- declarator_t *declarator;
- declarator_list_t *declarator_list;
- statement_t *statement;
- statement_list_t *stmt_list;
- ifref_t *ifref;
- ifref_list_t *ifref_list;
- char *str;
- UUID *uuid;
- unsigned int num;
- double dbl;
- interface_info_t ifinfo;
- typelib_t *typelib;
- struct _import_t *import;
- struct _decl_spec_t *declspec;
- enum storage_class stgclass;
- }
- %token <str> aIDENTIFIER
- %token <str> aKNOWNTYPE
- %token <num> aNUM aHEXNUM
- %token <dbl> aDOUBLE
- %token <str> aSTRING aWSTRING aSQSTRING
- %token <uuid> aUUID
- %token aEOF
- %token SHL SHR
- %token MEMBERPTR
- %token EQUALITY INEQUALITY
- %token GREATEREQUAL LESSEQUAL
- %token LOGICALOR LOGICALAND
- %token ELLIPSIS
- %token tAGGREGATABLE tALLOCATE tANNOTATION tAPPOBJECT tASYNC tASYNCUUID
- %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
- %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
- %token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
- %token tCONTEXTHANDLESERIALIZE tCONTROL tCPPQUOTE
- %token tDECODE tDEFAULT tDEFAULTBIND
- %token tDEFAULTCOLLELEM
- %token tDEFAULTVALUE
- %token tDEFAULTVTABLE
- %token tDISABLECONSISTENCYCHECK tDISPLAYBIND
- %token tDISPINTERFACE
- %token tDLLNAME tDOUBLE tDUAL
- %token tENABLEALLOCATE tENCODE tENDPOINT
- %token tENTRY tENUM tERRORSTATUST
- %token tEXPLICITHANDLE tEXTERN
- %token tFALSE
- %token tFASTCALL tFAULTSTATUS
- %token tFLOAT tFORCEALLOCATE
- %token tHANDLE
- %token tHANDLET
- %token tHELPCONTEXT tHELPFILE
- %token tHELPSTRING tHELPSTRINGCONTEXT tHELPSTRINGDLL
- %token tHIDDEN
- %token tHYPER tID tIDEMPOTENT
- %token tIGNORE tIIDIS
- %token tIMMEDIATEBIND
- %token tIMPLICITHANDLE
- %token tIMPORT tIMPORTLIB
- %token tIN tIN_LINE tINLINE
- %token tINPUTSYNC
- %token tINT tINT3264 tINT64
- %token tINTERFACE
- %token tLCID
- %token tLENGTHIS tLIBRARY
- %token tLICENSED tLOCAL
- %token tLONG
- %token tMAYBE tMESSAGE
- %token tMETHODS
- %token tMODULE
- %token tNOCODE tNONBROWSABLE
- %token tNONCREATABLE
- %token tNONEXTENSIBLE
- %token tNOTIFY tNOTIFYFLAG
- %token tNULL
- %token tOBJECT tODL tOLEAUTOMATION
- %token tOPTIMIZE tOPTIONAL
- %token tOUT
- %token tPARTIALIGNORE tPASCAL
- %token tPOINTERDEFAULT
- %token tPROGID tPROPERTIES
- %token tPROPGET tPROPPUT tPROPPUTREF
- %token tPROXY tPTR
- %token tPUBLIC
- %token tRANGE
- %token tREADONLY tREF
- %token tREGISTER tREPRESENTAS
- %token tREQUESTEDIT
- %token tRESTRICTED
- %token tRETVAL
- %token tSAFEARRAY
- %token tSHORT
- %token tSIGNED
- %token tSIZEIS tSIZEOF
- %token tSMALL
- %token tSOURCE
- %token tSTATIC
- %token tSTDCALL
- %token tSTRICTCONTEXTHANDLE
- %token tSTRING tSTRUCT
- %token tSWITCH tSWITCHIS tSWITCHTYPE
- %token tTHREADING tTRANSMITAS
- %token tTRUE
- %token tTYPEDEF
- %token tUIDEFAULT tUNION
- %token tUNIQUE
- %token tUNSIGNED
- %token tUSESGETLASTERROR tUSERMARSHAL tUUID
- %token tV1ENUM
- %token tVARARG
- %token tVERSION tVIPROGID
- %token tVOID
- %token tWCHAR tWIREMARSHAL
- %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
- %type <attr> attribute type_qualifier function_specifier
- %type <attr_list> m_attributes attributes attrib_list m_type_qual_list
- %type <str_list> str_list
- %type <expr> m_expr expr expr_const expr_int_const array m_bitfield
- %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
- %type <ifinfo> interfacehdr
- %type <stgclass> storage_cls_spec
- %type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
- %type <type> inherit interface interfacedef interfacedec
- %type <type> dispinterface dispinterfacehdr dispinterfacedef
- %type <type> module modulehdr moduledef
- %type <type> base_type int_std
- %type <type> enumdef structdef uniondef typedecl
- %type <type> type
- %type <ifref> coclass_int
- %type <ifref_list> coclass_ints
- %type <var> arg ne_union_field union_field s_field case enum declaration
- %type <var> funcdef
- %type <var_list> m_args arg_list args dispint_meths
- %type <var_list> fields ne_union_fields cases enums enum_list dispint_props field
- %type <var> m_ident ident
- %type <declarator> declarator direct_declarator init_declarator struct_declarator
- %type <declarator> m_any_declarator any_declarator any_declarator_no_direct any_direct_declarator
- %type <declarator> m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator
- %type <declarator_list> declarator_list struct_declarator_list
- %type <type> coclass coclasshdr coclassdef
- %type <num> pointer_type threading_type version
- %type <str> libraryhdr callconv cppquote importlib import t_ident
- %type <uuid> uuid_string
- %type <import> import_start
- %type <typelib> library_start librarydef
- %type <statement> statement typedef
- %type <stmt_list> gbl_statements imp_statements int_statements
- %left ','
- %right '?' ':'
- %left LOGICALOR
- %left LOGICALAND
- %left '|'
- %left '^'
- %left '&'
- %left EQUALITY INEQUALITY
- %left '<' '>' LESSEQUAL GREATEREQUAL
- %left SHL SHR
- %left '-' '+'
- %left '*' '/' '%'
- %right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
- %left '.' MEMBERPTR '[' ']'
- %%
- input: gbl_statements { fix_incomplete();
- check_statements($1, FALSE);
- check_all_user_types($1);
- write_header($1);
- write_id_data($1);
- write_proxies($1);
- write_client($1);
- write_server($1);
- write_regscript($1);
- write_dlldata($1);
- write_local_stubs($1);
- }
- ;
- gbl_statements: { $$ = NULL; }
- | gbl_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); }
- | gbl_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
- | gbl_statements coclass ';' { $$ = $1;
- reg_type($2, $2->name, 0);
- }
- | gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
- reg_type($2, $2->name, 0);
- }
- | gbl_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
- | gbl_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
- | gbl_statements statement { $$ = append_statement($1, $2); }
- ;
- imp_statements: { $$ = NULL; }
- | imp_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); }
- | imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
- | imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, 0); }
- | imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
- reg_type($2, $2->name, 0);
- }
- | imp_statements moduledef { $$ = append_statement($1, make_statement_module($2)); }
- | imp_statements statement { $$ = append_statement($1, $2); }
- | imp_statements importlib { $$ = append_statement($1, make_statement_importlib($2)); }
- | imp_statements librarydef { $$ = append_statement($1, make_statement_library($2)); }
- ;
- int_statements: { $$ = NULL; }
- | int_statements statement { $$ = append_statement($1, $2); }
- ;
- semicolon_opt:
- | ';'
- ;
- statement:
- cppquote { $$ = make_statement_cppquote($1); }
- | typedecl ';' { $$ = make_statement_type_decl($1); }
- | declaration ';' { $$ = make_statement_declaration($1); }
- | import { $$ = make_statement_import($1); }
- | typedef ';' { $$ = $1; }
- ;
- typedecl:
- enumdef
- | tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); }
- | structdef
- | tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
- | uniondef
- | tUNION aIDENTIFIER { $$ = type_new_nonencapsulated_union($2, FALSE, NULL); }
- | attributes enumdef { $$ = $2; $$->attrs = check_enum_attrs($1); }
- | attributes structdef { $$ = $2; $$->attrs = check_struct_attrs($1); }
- | attributes uniondef { $$ = $2; $$->attrs = check_union_attrs($1); }
- ;
- cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; }
- ;
- import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
- $$ = xmalloc(sizeof(struct _import_t));
- $$->name = $2;
- $$->import_performed = do_import($2);
- if (!$$->import_performed) yychar = aEOF;
- }
- ;
- import: import_start imp_statements aEOF { $$ = $1->name;
- if ($1->import_performed) pop_import();
- free($1);
- }
- ;
- importlib: tIMPORTLIB '(' aSTRING ')'
- semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3); }
- ;
- libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
- ;
- library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1));
- if (!parse_only) start_typelib($$);
- }
- ;
- librarydef: library_start imp_statements '}'
- semicolon_opt { $$ = $1;
- $$->stmts = $2;
- if (!parse_only) end_typelib();
- }
- ;
- m_args: { $$ = NULL; }
- | args
- ;
- arg_list: arg { check_arg_attrs($1); $$ = append_var( NULL, $1 ); }
- | arg_list ',' arg { check_arg_attrs($3); $$ = append_var( $1, $3 ); }
- ;
- args: arg_list
- | arg_list ',' ELLIPSIS { $$ = append_var( $1, make_var(strdup("...")) ); }
- ;
- /* split into two rules to get bison to resolve a tVOID conflict */
- arg: attributes decl_spec m_any_declarator { if ($2->stgclass != STG_NONE && $2->stgclass != STG_REGISTER)
- error_loc("invalid storage class for function parameter\n");
- $$ = declare_var($1, $2, $3, TRUE);
- free($2); free($3);
- }
- | decl_spec m_any_declarator { if ($1->stgclass != STG_NONE && $1->stgclass != STG_REGISTER)
- error_loc("invalid storage class for function parameter\n");
- $$ = declare_var(NULL, $1, $2, TRUE);
- free($1); free($2);
- }
- ;
- array: '[' expr ']' { $$ = $2;
- if (!$$->is_const)
- error_loc("array dimension is not an integer constant\n");
- }
- | '[' '*' ']' { $$ = make_expr(EXPR_VOID); }
- | '[' ']' { $$ = make_expr(EXPR_VOID); }
- ;
- m_attributes: { $$ = NULL; }
- | attributes
- ;
- attributes:
- '[' attrib_list ']' { $$ = $2; }
- ;
- attrib_list: attribute { $$ = append_attr( NULL, $1 ); }
- | attrib_list ',' attribute { $$ = append_attr( $1, $3 ); }
- | attrib_list ']' '[' attribute { $$ = append_attr( $1, $4 ); }
- ;
- str_list: aSTRING { $$ = append_str( NULL, $1 ); }
- | str_list ',' aSTRING { $$ = append_str( $1, $3 ); }
- ;
- attribute: { $$ = NULL; }
- | tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
- | tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
- | tAPPOBJECT { $$ = make_attr(ATTR_APPOBJECT); }
- | tASYNC { $$ = make_attr(ATTR_ASYNC); }
- | tAUTOHANDLE { $$ = make_attr(ATTR_AUTO_HANDLE); }
- | tBINDABLE { $$ = make_attr(ATTR_BINDABLE); }
- | tBROADCAST { $$ = make_attr(ATTR_BROADCAST); }
- | tCALLAS '(' ident ')' { $$ = make_attrp(ATTR_CALLAS, $3); }
- | tCASE '(' expr_list_int_const ')' { $$ = make_attrp(ATTR_CASE, $3); }
- | tCODE { $$ = make_attr(ATTR_CODE); }
- | tCOMMSTATUS { $$ = make_attr(ATTR_COMMSTATUS); }
- | tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
- | tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
- | tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
- | tCONTROL { $$ = make_attr(ATTR_CONTROL); }
- | tDECODE { $$ = make_attr(ATTR_DECODE); }
- | tDEFAULT { $$ = make_attr(ATTR_DEFAULT); }
- | tDEFAULTBIND { $$ = make_attr(ATTR_DEFAULTBIND); }
- | tDEFAULTCOLLELEM { $$ = make_attr(ATTR_DEFAULTCOLLELEM); }
- | tDEFAULTVALUE '(' expr_const ')' { $$ = make_attrp(ATTR_DEFAULTVALUE, $3); }
- | tDEFAULTVTABLE { $$ = make_attr(ATTR_DEFAULTVTABLE); }
- | tDISABLECONSISTENCYCHECK { $$ = make_attr(ATTR_DISABLECONSISTENCYCHECK); }
- | tDISPLAYBIND { $$ = make_attr(ATTR_DISPLAYBIND); }
- | tDLLNAME '(' aSTRING ')' { $$ = make_attrp(ATTR_DLLNAME, $3); }
- | tDUAL { $$ = make_attr(ATTR_DUAL); }
- | tENABLEALLOCATE { $$ = make_attr(ATTR_ENABLEALLOCATE); }
- | tENCODE { $$ = make_attr(ATTR_ENCODE); }
- | tENDPOINT '(' str_list ')' { $$ = make_attrp(ATTR_ENDPOINT, $3); }
- | tENTRY '(' expr_const ')' { $$ = make_attrp(ATTR_ENTRY, $3); }
- | tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
- | tFAULTSTATUS { $$ = make_attr(ATTR_FAULTSTATUS); }
- | tFORCEALLOCATE { $$ = make_attr(ATTR_FORCEALLOCATE); }
- | tHANDLE { $$ = make_attr(ATTR_HANDLE); }
- | tHELPCONTEXT '(' expr_int_const ')' { $$ = make_attrp(ATTR_HELPCONTEXT, $3); }
- | tHELPFILE '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPFILE, $3); }
- | tHELPSTRING '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRING, $3); }
- | tHELPSTRINGCONTEXT '(' expr_int_const ')' { $$ = make_attrp(ATTR_HELPSTRINGCONTEXT, $3); }
- | tHELPSTRINGDLL '(' aSTRING ')' { $$ = make_attrp(ATTR_HELPSTRINGDLL, $3); }
- | tHIDDEN { $$ = make_attr(ATTR_HIDDEN); }
- | tID '(' expr_int_const ')' { $$ = make_attrp(ATTR_ID, $3); }
- | tIDEMPOTENT { $$ = make_attr(ATTR_IDEMPOTENT); }
- | tIGNORE { $$ = make_attr(ATTR_IGNORE); }
- | tIIDIS '(' expr ')' { $$ = make_attrp(ATTR_IIDIS, $3); }
- | tIMMEDIATEBIND { $$ = make_attr(ATTR_IMMEDIATEBIND); }
- | tIMPLICITHANDLE '(' arg ')' { $$ = make_attrp(ATTR_IMPLICIT_HANDLE, $3); }
- | tIN { $$ = make_attr(ATTR_IN); }
- | tINPUTSYNC { $$ = make_attr(ATTR_INPUTSYNC); }
- | tLENGTHIS '(' m_exprs ')' { $$ = make_attrp(ATTR_LENGTHIS, $3); }
- | tLCID '(' expr_int_const ')' { $$ = make_attrp(ATTR_LIBLCID, $3); }
- | tLCID { $$ = make_attr(ATTR_PARAMLCID); }
- | tLICENSED { $$ = make_attr(ATTR_LICENSED); }
- | tLOCAL { $$ = make_attr(ATTR_LOCAL); }
- | tMAYBE { $$ = make_attr(ATTR_MAYBE); }
- | tMESSAGE { $$ = make_attr(ATTR_MESSAGE); }
- | tNOCODE { $$ = make_attr(ATTR_NOCODE); }
- | tNONBROWSABLE { $$ = make_attr(ATTR_NONBROWSABLE); }
- | tNONCREATABLE { $$ = make_attr(ATTR_NONCREATABLE); }
- | tNONEXTENSIBLE { $$ = make_attr(ATTR_NONEXTENSIBLE); }
- | tNOTIFY { $$ = make_attr(ATTR_NOTIFY); }
- | tNOTIFYFLAG { $$ = make_attr(ATTR_NOTIFYFLAG); }
- | tOBJECT { $$ = make_attr(ATTR_OBJECT); }
- | tODL { $$ = make_attr(ATTR_ODL); }
- | tOLEAUTOMATION { $$ = make_attr(ATTR_OLEAUTOMATION); }
- | tOPTIMIZE '(' aSTRING ')' { $$ = make_attrp(ATTR_OPTIMIZE, $3); }
- | tOPTIONAL { $$ = make_attr(ATTR_OPTIONAL); }
- | tOUT { $$ = make_attr(ATTR_OUT); }
- | tPARTIALIGNORE { $$ = make_attr(ATTR_PARTIALIGNORE); }
- | tPOINTERDEFAULT '(' pointer_type ')' { $$ = make_attrv(ATTR_POINTERDEFAULT, $3); }
- | tPROGID '(' aSTRING ')' { $$ = make_attrp(ATTR_PROGID, $3); }
- | tPROPGET { $$ = make_attr(ATTR_PROPGET); }
- | tPROPPUT { $$ = make_attr(ATTR_PROPPUT); }
- | tPROPPUTREF { $$ = make_attr(ATTR_PROPPUTREF); }
- | tPROXY { $$ = make_attr(ATTR_PROXY); }
- | tPUBLIC { $$ = make_attr(ATTR_PUBLIC); }
- | tRANGE '(' expr_int_const ',' expr_int_const ')'
- { expr_list_t *list = append_expr( NULL, $3 );
- list = append_expr( list, $5 );
- $$ = make_attrp(ATTR_RANGE, list); }
- | tREADONLY { $$ = make_attr(ATTR_READONLY); }
- | tREPRESENTAS '(' type ')' { $$ = make_attrp(ATTR_REPRESENTAS, $3); }
- | tREQUESTEDIT { $$ = make_attr(ATTR_REQUESTEDIT); }
- | tRESTRICTED { $$ = make_attr(ATTR_RESTRICTED); }
- | tRETVAL { $$ = make_attr(ATTR_RETVAL); }
- | tSIZEIS '(' m_exprs ')' { $$ = make_attrp(ATTR_SIZEIS, $3); }
- | tSOURCE { $$ = make_attr(ATTR_SOURCE); }
- | tSTRICTCONTEXTHANDLE { $$ = make_attr(ATTR_STRICTCONTEXTHANDLE); }
- | tSTRING { $$ = make_attr(ATTR_STRING); }
- | tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); }
- | tSWITCHTYPE '(' type ')' { $$ = make_attrp(ATTR_SWITCHTYPE, $3); }
- | tTRANSMITAS '(' type ')' { $$ = make_attrp(ATTR_TRANSMITAS, $3); }
- | tTHREADING '(' threading_type ')' { $$ = make_attrv(ATTR_THREADING, $3); }
- | tUIDEFAULT { $$ = make_attr(ATTR_UIDEFAULT); }
- | tUSESGETLASTERROR { $$ = make_attr(ATTR_USESGETLASTERROR); }
- | tUSERMARSHAL '(' type ')' { $$ = make_attrp(ATTR_USERMARSHAL, $3); }
- | tUUID '(' uuid_string ')' { $$ = make_attrp(ATTR_UUID, $3); }
- | tV1ENUM { $$ = make_attr(ATTR_V1ENUM); }
- | tVARARG { $$ = make_attr(ATTR_VARARG); }
- | tVERSION '(' version ')' { $$ = make_attrv(ATTR_VERSION, $3); }
- | tVIPROGID '(' aSTRING ')' { $$ = make_attrp(ATTR_VIPROGID, $3); }
- | tWIREMARSHAL '(' type ')' { $$ = make_attrp(ATTR_WIREMARSHAL, $3); }
- | pointer_type { $$ = make_attrv(ATTR_POINTERTYPE, $1); }
- ;
- uuid_string:
- aUUID
- | aSTRING { if (!is_valid_uuid($1))
- error_loc("invalid UUID: %s\n", $1);
- $$ = parse_uuid($1); }
- ;
- callconv: tCDECL { $$ = xstrdup("__cdecl"); }
- | tFASTCALL { $$ = xstrdup("__fastcall"); }
- | tPASCAL { $$ = xstrdup("__pascal"); }
- | tSTDCALL { $$ = xstrdup("__stdcall"); }
- ;
- cases: { $$ = NULL; }
- | cases case { $$ = append_var( $1, $2 ); }
- ;
- case: tCASE expr_int_const ':' union_field { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 ));
- $$ = $4; if (!$$) $$ = make_var(NULL);
- $$->attrs = append_attr( $$->attrs, a );
- }
- | tDEFAULT ':' union_field { attr_t *a = make_attr(ATTR_DEFAULT);
- $$ = $3; if (!$$) $$ = make_var(NULL);
- $$->attrs = append_attr( $$->attrs, a );
- }
- ;
- enums: { $$ = NULL; }
- | enum_list ',' { $$ = $1; }
- | enum_list
- ;
- enum_list: enum { if (!$1->eval)
- $1->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
- $$ = append_var( NULL, $1 );
- }
- | enum_list ',' enum { if (!$3->eval)
- {
- var_t *last = LIST_ENTRY( list_tail($$), var_t, entry );
- $3->eval = make_exprl(EXPR_NUM, last->eval->cval + 1);
- }
- $$ = append_var( $1, $3 );
- }
- ;
- enum: ident '=' expr_int_const { $$ = reg_const($1);
- $$->eval = $3;
- $$->type = type_new_int(TYPE_BASIC_INT, 0);
- }
- | ident { $$ = reg_const($1);
- $$->type = type_new_int(TYPE_BASIC_INT, 0);
- }
- ;
- enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, TRUE, $4); }
- ;
- m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
- | m_exprs ',' m_expr { $$ = append_expr( $1, $3 ); }
- ;
- m_expr: { $$ = make_expr(EXPR_VOID); }
- | expr
- ;
- expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); }
- | aHEXNUM { $$ = make_exprl(EXPR_HEXNUM, $1); }
- | aDOUBLE { $$ = make_exprd(EXPR_DOUBLE, $1); }
- | tFALSE { $$ = make_exprl(EXPR_TRUEFALSE, 0); }
- | tNULL { $$ = make_exprl(EXPR_NUM, 0); }
- | tTRUE { $$ = make_exprl(EXPR_TRUEFALSE, 1); }
- | aSTRING { $$ = make_exprs(EXPR_STRLIT, $1); }
- | aWSTRING { $$ = make_exprs(EXPR_WSTRLIT, $1); }
- | aSQSTRING { $$ = make_exprs(EXPR_CHARCONST, $1); }
- | aIDENTIFIER { $$ = make_exprs(EXPR_IDENTIFIER, $1); }
- | expr '?' expr ':' expr { $$ = make_expr3(EXPR_COND, $1, $3, $5); }
- | expr LOGICALOR expr { $$ = make_expr2(EXPR_LOGOR, $1, $3); }
- | expr LOGICALAND expr { $$ = make_expr2(EXPR_LOGAND, $1, $3); }
- | expr '|' expr { $$ = make_expr2(EXPR_OR , $1, $3); }
- | expr '^' expr { $$ = make_expr2(EXPR_XOR, $1, $3); }
- | expr '&' expr { $$ = make_expr2(EXPR_AND, $1, $3); }
- | expr EQUALITY expr { $$ = make_expr2(EXPR_EQUALITY, $1, $3); }
- | expr INEQUALITY expr { $$ = make_expr2(EXPR_INEQUALITY, $1, $3); }
- | expr '>' expr { $$ = make_expr2(EXPR_GTR, $1, $3); }
- | expr '<' expr { $$ = make_expr2(EXPR_LESS, $1, $3); }
- | expr GREATEREQUAL expr { $$ = make_expr2(EXPR_GTREQL, $1, $3); }
- | expr LESSEQUAL expr { $$ = make_expr2(EXPR_LESSEQL, $1, $3); }
- | expr SHL expr { $$ = make_expr2(EXPR_SHL, $1, $3); }
- | expr SHR expr { $$ = make_expr2(EXPR_SHR, $1, $3); }
- | expr '+' expr { $$ = make_expr2(EXPR_ADD, $1, $3); }
- | expr '-' expr { $$ = make_expr2(EXPR_SUB, $1, $3); }
- | expr '%' expr { $$ = make_expr2(EXPR_MOD, $1, $3); }
- | expr '*' expr { $$ = make_expr2(EXPR_MUL, $1, $3); }
- | expr '/' expr { $$ = make_expr2(EXPR_DIV, $1, $3); }
- | '!' expr { $$ = make_expr1(EXPR_LOGNOT, $2); }
- | '~' expr { $$ = make_expr1(EXPR_NOT, $2); }
- | '+' expr %prec POS { $$ = make_expr1(EXPR_POS, $2); }
- | '-' expr %prec NEG { $$ = make_expr1(EXPR_NEG, $2); }
- | '&' expr %prec ADDRESSOF { $$ = make_expr1(EXPR_ADDRESSOF, $2); }
- | '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); }
- | expr MEMBERPTR aIDENTIFIER { $$ = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, $1), make_exprs(EXPR_IDENTIFIER, $3)); }
- | expr '.' aIDENTIFIER { $$ = make_expr2(EXPR_MEMBER, $1, make_exprs(EXPR_IDENTIFIER, $3)); }
- | '(' decl_spec m_abstract_declarator ')' expr %prec CAST
- { $$ = make_exprt(EXPR_CAST, declare_var(NULL, $2, $3, 0), $5); free($2); free($3); }
- | tSIZEOF '(' decl_spec m_abstract_declarator ')'
- { $$ = make_exprt(EXPR_SIZEOF, declare_var(NULL, $3, $4, 0), NULL); free($3); free($4); }
- | expr '[' expr ']' { $$ = make_expr2(EXPR_ARRAY, $1, $3); }
- | '(' expr ')' { $$ = $2; }
- ;
- expr_list_int_const: expr_int_const { $$ = append_expr( NULL, $1 ); }
- | expr_list_int_const ',' expr_int_const { $$ = append_expr( $1, $3 ); }
- ;
- expr_int_const: expr { $$ = $1;
- if (!$$->is_const)
- error_loc("expression is not an integer constant\n");
- }
- ;
- expr_const: expr { $$ = $1;
- if (!$$->is_const && $$->type != EXPR_STRLIT && $$->type != EXPR_WSTRLIT)
- error_loc("expression is not constant\n");
- }
- ;
- fields: { $$ = NULL; }
- | fields field { $$ = append_var_list($1, $2); }
- ;
- field: m_attributes decl_spec struct_declarator_list ';'
- { const char *first = LIST_ENTRY(list_head($3), declarator_t, entry)->var->name;
- check_field_attrs(first, $1);
- $$ = set_var_types($1, $2, $3);
- }
- | m_attributes uniondef ';' { var_t *v = make_var(NULL);
- v->type = $2; v->attrs = $1;
- $$ = append_var(NULL, v);
- }
- ;
- ne_union_field:
- s_field ';' { $$ = $1; }
- | attributes ';' { $$ = make_var(NULL); $$->attrs = $1; }
- ;
- ne_union_fields: { $$ = NULL; }
- | ne_union_fields ne_union_field { $$ = append_var( $1, $2 ); }
- ;
- union_field:
- s_field ';' { $$ = $1; }
- | ';' { $$ = NULL; }
- ;
- s_field: m_attributes decl_spec declarator { $$ = declare_var(check_field_attrs($3->var->name, $1),
- $2, $3, FALSE);
- free($3);
- }
- | m_attributes structdef { var_t *v = make_var(NULL);
- v->type = $2; v->attrs = $1;
- $$ = v;
- }
- ;
- funcdef: declaration { $$ = $1;
- if (type_get_type($$->type) != TYPE_FUNCTION)
- error_loc("only methods may be declared inside the methods section of a dispinterface\n");
- check_function_attrs($$->name, $$->attrs);
- }
- ;
- declaration:
- attributes decl_spec init_declarator
- { $$ = declare_var($1, $2, $3, FALSE);
- free($3);
- }
- | decl_spec init_declarator { $$ = declare_var(NULL, $1, $2, FALSE);
- free($2);
- }
- ;
- m_ident: { $$ = NULL; }
- | ident
- ;
- t_ident: { $$ = NULL; }
- | aIDENTIFIER { $$ = $1; }
- | aKNOWNTYPE { $$ = $1; }
- ;
- ident: aIDENTIFIER { $$ = make_var($1); }
- /* some "reserved words" used in attributes are also used as field names in some MS IDL files */
- | aKNOWNTYPE { $$ = make_var($<str>1); }
- ;
- base_type: tBYTE { $$ = find_type_or_error($<str>1, 0); }
- | tWCHAR { $$ = find_type_or_error($<str>1, 0); }
- | int_std
- | tSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), -1); }
- | tUNSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), 1); }
- | tUNSIGNED { $$ = type_new_int(TYPE_BASIC_INT, 1); }
- | tFLOAT { $$ = find_type_or_error($<str>1, 0); }
- | tDOUBLE { $$ = find_type_or_error($<str>1, 0); }
- | tBOOLEAN { $$ = find_type_or_error($<str>1, 0); }
- | tERRORSTATUST { $$ = find_type_or_error($<str>1, 0); }
- | tHANDLET { $$ = find_type_or_error($<str>1, 0); }
- ;
- m_int:
- | tINT
- ;
- int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
- | tSHORT m_int { $$ = type_new_int(TYPE_BASIC_INT16, 0); }
- | tSMALL { $$ = type_new_int(TYPE_BASIC_INT8, 0); }
- | tLONG m_int { $$ = type_new_int(TYPE_BASIC_INT32, 0); }
- | tHYPER m_int { $$ = type_new_int(TYPE_BASIC_HYPER, 0); }
- | tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 0); }
- | tCHAR { $$ = type_new_int(TYPE_BASIC_CHAR, 0); }
- | tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); }
- ;
- coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); }
- | tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0);
- if (type_get_type_detect_alias($$) != TYPE_COCLASS)
- error_loc("%s was not declared a coclass at %s:%d\n",
- $2, $$->loc_info.input_name,
- $$->loc_info.line_number);
- }
- ;
- coclasshdr: attributes coclass { $$ = $2;
- check_def($$);
- $$->attrs = check_coclass_attrs($2->name, $1);
- }
- ;
- coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
- { $$ = type_coclass_define($1, $3); }
- ;
- coclass_ints: { $$ = NULL; }
- | coclass_ints coclass_int { $$ = append_ifref( $1, $2 ); }
- ;
- coclass_int:
- m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; }
- ;
- dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, 0); }
- | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, 0); }
- ;
- dispinterfacehdr: attributes dispinterface { attr_t *attrs;
- $$ = $2;
- check_def($$);
- attrs = make_attr(ATTR_DISPINTERFACE);
- $$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
- $$->defined = TRUE;
- }
- ;
- dispint_props: tPROPERTIES ':' { $$ = NULL; }
- | dispint_props s_field ';' { $$ = append_var( $1, $2 ); }
- ;
- dispint_meths: tMETHODS ':' { $$ = NULL; }
- | dispint_meths funcdef ';' { $$ = append_var( $1, $2 ); }
- ;
- dispinterfacedef: dispinterfacehdr '{'
- dispint_props
- dispint_meths
- '}' { $$ = $1;
- type_dispinterface_define($$, $3, $4);
- }
- | dispinterfacehdr
- '{' interface ';' '}' { $$ = $1;
- type_dispinterface_define_from_iface($$, $3);
- }
- ;
- inherit: { $$ = NULL; }
- | ':' aKNOWNTYPE { $$ = find_type_or_error2($2, 0); }
- ;
- interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, 0); }
- | tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, 0); }
- ;
- interfacehdr: attributes interface { $$.interface = $2;
- $$.old_pointer_default = pointer_default;
- if (is_attr($1, ATTR_POINTERDEFAULT))
- pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
- check_def($2);
- $2->attrs = check_iface_attrs($2->name, $1);
- $2->defined = TRUE;
- }
- ;
- interfacedef: interfacehdr inherit
- '{' int_statements '}' semicolon_opt { $$ = $1.interface;
- type_interface_define($$, $2, $4);
- pointer_default = $1.old_pointer_default;
- }
- /* MIDL is able to import the definition of a base class from inside the
- * definition of a derived class, I'll try to support it with this rule */
- | interfacehdr ':' aIDENTIFIER
- '{' import int_statements '}'
- semicolon_opt { $$ = $1.interface;
- type_interface_define($$, find_type_or_error2($3, 0), $6);
- pointer_default = $1.old_pointer_default;
- }
- | dispinterfacedef semicolon_opt { $$ = $1; }
- ;
- interfacedec:
- interface ';' { $$ = $1; }
- | dispinterface ';' { $$ = $1; }
- ;
- module: tMODULE aIDENTIFIER { $$ = type_new_module($2); }
- | tMODULE aKNOWNTYPE { $$ = type_new_module($2); }
- ;
- modulehdr: attributes module { $$ = $2;
- $$->attrs = check_module_attrs($2->name, $1);
- }
- ;
- moduledef: modulehdr '{' int_statements '}'
- semicolon_opt { $$ = $1;
- type_module_define($$, $3);
- }
- ;
- storage_cls_spec:
- tEXTERN { $$ = STG_EXTERN; }
- | tSTATIC { $$ = STG_STATIC; }
- | tREGISTER { $$ = STG_REGISTER; }
- ;
- function_specifier:
- tINLINE { $$ = make_attr(ATTR_INLINE); }
- ;
- type_qualifier:
- tCONST { $$ = make_attr(ATTR_CONST); }
- ;
- m_type_qual_list: { $$ = NULL; }
- | m_type_qual_list type_qualifier { $$ = append_attr($1, $2); }
- ;
- decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); }
- | decl_spec_no_type type m_decl_spec_no_type
- { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); }
- ;
- m_decl_spec_no_type: { $$ = NULL; }
- | decl_spec_no_type
- ;
- decl_spec_no_type:
- type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
- | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
- | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); }
- ;
- declarator:
- '*' m_type_qual_list declarator %prec PPTR
- { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
- | callconv declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- | direct_declarator
- ;
- direct_declarator:
- ident { $$ = make_declarator($1); }
- | '(' declarator ')' { $$ = $2; }
- | direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); }
- | direct_declarator '(' m_args ')' { $$ = $1;
- $$->func_type = append_ptrchain_type($$->type, type_new_function($3));
- $$->type = NULL;
- }
- ;
- /* abstract declarator */
- abstract_declarator:
- '*' m_type_qual_list m_abstract_declarator %prec PPTR
- { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
- | callconv m_abstract_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- | abstract_direct_declarator
- ;
- /* abstract declarator without accepting direct declarator */
- abstract_declarator_no_direct:
- '*' m_type_qual_list m_any_declarator %prec PPTR
- { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
- | callconv m_any_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- ;
- /* abstract declarator or empty */
- m_abstract_declarator: { $$ = make_declarator(NULL); }
- | abstract_declarator
- ;
- /* abstract direct declarator */
- abstract_direct_declarator:
- '(' abstract_declarator_no_direct ')' { $$ = $2; }
- | abstract_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); }
- | array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); }
- | '(' m_args ')'
- { $$ = make_declarator(NULL);
- $$->func_type = append_ptrchain_type($$->type, type_new_function($2));
- $$->type = NULL;
- }
- | abstract_direct_declarator '(' m_args ')'
- { $$ = $1;
- $$->func_type = append_ptrchain_type($$->type, type_new_function($3));
- $$->type = NULL;
- }
- ;
- /* abstract or non-abstract declarator */
- any_declarator:
- '*' m_type_qual_list m_any_declarator %prec PPTR
- { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- | any_direct_declarator
- ;
- /* abstract or non-abstract declarator without accepting direct declarator */
- any_declarator_no_direct:
- '*' m_type_qual_list m_any_declarator %prec PPTR
- { $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- ;
- /* abstract or non-abstract declarator or empty */
- m_any_declarator: { $$ = make_declarator(NULL); }
- | any_declarator
- ;
- /* abstract or non-abstract direct declarator. note: direct declarators
- * aren't accepted inside brackets to avoid ambiguity with the rule for
- * function arguments */
- any_direct_declarator:
- ident { $$ = make_declarator($1); }
- | '(' any_declarator_no_direct ')' { $$ = $2; }
- | any_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); }
- | array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); }
- | '(' m_args ')'
- { $$ = make_declarator(NULL);
- $$->func_type = append_ptrchain_type($$->type, type_new_function($2));
- $$->type = NULL;
- }
- | any_direct_declarator '(' m_args ')'
- { $$ = $1;
- $$->func_type = append_ptrchain_type($$->type, type_new_function($3));
- $$->type = NULL;
- }
- ;
- declarator_list:
- declarator { $$ = append_declarator( NULL, $1 ); }
- | declarator_list ',' declarator { $$ = append_declarator( $1, $3 ); }
- ;
- m_bitfield: { $$ = NULL; }
- | ':' expr_const { $$ = $2; }
- ;
- struct_declarator: any_declarator m_bitfield { $$ = $1; $$->bits = $2;
- if (!$$->bits && !$$->var->name)
- error_loc("unnamed fields are not allowed\n");
- }
- ;
- struct_declarator_list:
- struct_declarator { $$ = append_declarator( NULL, $1 ); }
- | struct_declarator_list ',' struct_declarator
- { $$ = append_declarator( $1, $3 ); }
- ;
- init_declarator:
- declarator { $$ = $1; }
- | declarator '=' expr_const { $$ = $1; $1->var->eval = $3; }
- ;
- threading_type:
- tAPARTMENT { $$ = THREADING_APARTMENT; }
- | tNEUTRAL { $$ = THREADING_NEUTRAL; }
- | tSINGLE { $$ = THREADING_SINGLE; }
- | tFREE { $$ = THREADING_FREE; }
- | tBOTH { $$ = THREADING_BOTH; }
- ;
- pointer_type:
- tREF { $$ = RPC_FC_RP; }
- | tUNIQUE { $$ = RPC_FC_UP; }
- | tPTR { $$ = RPC_FC_FP; }
- ;
- structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, TRUE, $4); }
- ;
- type: tVOID { $$ = type_new_void(); }
- | aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
- | base_type { $$ = $1; }
- | enumdef { $$ = $1; }
- | tENUM aIDENTIFIER { $$ = type_new_enum($2, FALSE, NULL); }
- | structdef { $$ = $1; }
- | tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
- | uniondef { $$ = $1; }
- | tUNION aIDENTIFIER { $$ = type_new_nonencapsulated_union($2, FALSE, NULL); }
- | tSAFEARRAY '(' type ')' { $$ = make_safearray($3); }
- ;
- typedef: tTYPEDEF m_attributes decl_spec declarator_list
- { reg_typedefs($3, $4, check_typedef_attrs($2));
- $$ = make_statement_typedef($4);
- }
- ;
- uniondef: tUNION t_ident '{' ne_union_fields '}'
- { $$ = type_new_nonencapsulated_union($2, TRUE, $4); }
- | tUNION t_ident
- tSWITCH '(' s_field ')'
- m_ident '{' cases '}' { $$ = type_new_encapsulated_union($2, $5, $7, $9); }
- ;
- version:
- aNUM { $$ = MAKEVERSION($1, 0); }
- | aNUM '.' aNUM { $$ = MAKEVERSION($1, $3); }
- ;
- %%
- static void decl_builtin_basic(const char *name, enum type_basic_type type)
- {
- type_t *t = type_new_basic(type);
- reg_type(t, name, 0);
- }
- static void decl_builtin_alias(const char *name, type_t *t)
- {
- reg_type(type_new_alias(t, name), name, 0);
- }
- void init_types(void)
- {
- decl_builtin_basic("byte", TYPE_BASIC_BYTE);
- decl_builtin_basic("wchar_t", TYPE_BASIC_WCHAR);
- decl_builtin_basic("float", TYPE_BASIC_FLOAT);
- decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
- decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
- decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
- }
- static str_list_t *append_str(str_list_t *list, char *str)
- {
- struct str_list_entry_t *entry;
- if (!str) return list;
- if (!list)
- {
- list = xmalloc( sizeof(*list) );
- list_init( list );
- }
- entry = xmalloc( sizeof(*entry) );
- entry->str = str;
- list_add_tail( list, &entry->entry );
- return list;
- }
- static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
- {
- attr_t *attr_existing;
- if (!attr) return list;
- if (!list)
- {
- list = xmalloc( sizeof(*list) );
- list_init( list );
- }
- LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
- if (attr_existing->type == attr->type)
- {
- parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
- /* use the last attribute, like MIDL does */
- list_remove(&attr_existing->entry);
- break;
- }
- list_add_tail( list, &attr->entry );
- return list;
- }
- static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
- {
- attr_t *attr;
- if (!src) return dst;
- LIST_FOR_EACH_ENTRY(attr, src, attr_t, entry)
- if (attr->type == type)
- {
- list_remove(&attr->entry);
- return append_attr(dst, attr);
- }
- return dst;
- }
- static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list)
- {
- struct list *entry;
- if (!old_list) return new_list;
- while ((entry = list_head(old_list)))
- {
- attr_t *attr = LIST_ENTRY(entry, attr_t, entry);
- list_remove(entry);
- new_list = append_attr(new_list, attr);
- }
- return new_list;
- }
- static attr_list_t *dupattrs(const attr_list_t *list)
- {
- attr_list_t *new_list;
- const attr_t *attr;
- if (!list) return NULL;
- new_list = xmalloc( sizeof(*list) );
- list_init( new_list );
- LIST_FOR_EACH_ENTRY(attr, list, const attr_t, entry)
- {
- attr_t *new_attr = xmalloc(sizeof(*new_attr));
- *new_attr = *attr;
- list_add_tail(new_list, &new_attr->entry);
- }
- return new_list;
- }
- 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)
- {
- decl_spec_t *declspec = left ? left : right;
- if (!declspec)
- {
- declspec = xmalloc(sizeof(*declspec));
- declspec->type = NULL;
- declspec->attrs = NULL;
- declspec->stgclass = STG_NONE;
- }
- declspec->type = type;
- if (left && declspec != left)
- {
- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = left->stgclass;
- else if (left->stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
- assert(!left->type);
- free(left);
- }
- if (right && declspec != right)
- {
- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = right->stgclass;
- else if (right->stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
- assert(!right->type);
- free(right);
- }
- declspec->attrs = append_attr(declspec->attrs, attr);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = stgclass;
- else if (stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
- /* apply attributes to type */
- if (type && declspec->attrs)
- {
- attr_list_t *attrs;
- declspec->type = duptype(type, 1);
- attrs = dupattrs(type->attrs);
- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
- declspec->attrs = NULL;
- }
- return declspec;
- }
- static attr_t *make_attr(enum attr_type type)
- {
- attr_t *a = xmalloc(sizeof(attr_t));
- a->type = type;
- a->u.ival = 0;
- return a;
- }
- static attr_t *make_attrv(enum attr_type type, unsigned int val)
- {
- attr_t *a = xmalloc(sizeof(attr_t));
- a->type = type;
- a->u.ival = val;
- return a;
- }
- static attr_t *make_attrp(enum attr_type type, void *val)
- {
- attr_t *a = xmalloc(sizeof(attr_t));
- a->type = type;
- a->u.pval = val;
- return a;
- }
- static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
- {
- if (!expr) return list;
- if (!list)
- {
- list = xmalloc( sizeof(*list) );
- list_init( list );
- }
- list_add_tail( list, &expr->entry );
- return list;
- }
- static array_dims_t *append_array(array_dims_t *list, expr_t *expr)
- {
- if (!expr) return list;
- if (!list)
- {
- list = xmalloc( sizeof(*list) );
- list_init( list );
- }
- list_add_tail( list, &expr->entry );
- return list;
- }
- static struct list type_pool = LIST_INIT(type_pool);
- typedef struct
- {
- type_t data;
- struct list link;
- } type_pool_node_t;
- type_t *alloc_type(void)
- {
- type_pool_node_t *node = xmalloc(sizeof *node);
- list_add_tail(&type_pool, &node->link);
- return &node->data;
- }
- void set_all_tfswrite(int val)
- {
- type_pool_node_t *node;
- LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link)
- node->data.tfswrite = val;
- }
- void clear_all_offsets(void)
- {
- type_pool_node_t *node;
- LIST_FOR_EACH_ENTRY(node, &type_pool, type_pool_node_t, link)
- node->data.typestring_offset = node->data.ptrdesc = 0;
- }
- static void type_function_add_head_arg(type_t *type, var_t *arg)
- {
- if (!type->details.function->args)
- {
- type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
- list_init( type->details.function->args );
- }
- list_add_head( type->details.function->args, &arg->entry );
- }
- static int is_allowed_range_type(const type_t *type)
- {
- switch (type_get_type(type))
- {
- case TYPE_ENUM:
- return TRUE;
- case TYPE_BASIC:
- switch (type_basic_get_type(type))
- {
- case TYPE_BASIC_INT8:
- case TYPE_BASIC_INT16:
- case TYPE_BASIC_INT32:
- case TYPE_BASIC_INT64:
- case TYPE_BASIC_INT:
- case TYPE_BASIC_INT3264:
- case TYPE_BASIC_BYTE:
- case TYPE_BASIC_CHAR:
- case TYPE_BASIC_WCHAR:
- case TYPE_BASIC_HYPER:
- return TRUE;
- case TYPE_BASIC_FLOAT:
- case TYPE_BASIC_DOUBLE:
- case TYPE_BASIC_ERROR_STATUS_T:
- case TYPE_BASIC_HANDLE:
- return FALSE;
- }
- return FALSE;
- default:
- return FALSE;
- }
- }
- static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
- {
- type_t *ptrchain_type;
- if (!ptrchain)
- return type;
- for (ptrchain_type = ptrchain; type_pointer_get_ref(ptrchain_type); ptrchain_type = type_pointer_get_ref(ptrchain_type))
- ;
- assert(ptrchain_type->type_type == TYPE_POINTER);
- ptrchain_type->details.pointer.ref = type;
- return ptrchain;
- }
- static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
- int top)
- {
- var_t *v = decl->var;
- expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS);
- expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS);
- int sizeless;
- expr_t *dim;
- type_t **ptype;
- array_dims_t *arr = decl ? decl->array : NULL;
- type_t *func_type = decl ? decl->func_type : NULL;
- type_t *type = decl_spec->type;
- if (is_attr(type->attrs, ATTR_INLINE))
- {
- if (!func_type)
- error_loc("inline attribute applied to non-function type\n");
- else
- {
- type_t *t;
- /* move inline attribute from return type node to function node */
- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
- ;
- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
- }
- }
- /* add type onto the end of the pointers in pident->type */
- v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
- v->stgclass = decl_spec->stgclass;
- v->attrs = attrs;
- /* check for pointer attribute being applied to non-pointer, non-array
- * type */
- if (!arr)
- {
- int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
- const type_t *ptr = NULL;
- /* pointer attributes on the left side of the type belong to the function
- * pointer, if one is being declared */
- type_t **pt = func_type ? &func_ty…
Large files files are truncated, but you can click here to view the full file