From 621b4fa6971f5fc4590246f8250718cc76cf836c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Thu, 4 Feb 2021 17:43:43 +0100 Subject: [PATCH] widl: Distinguish interface declarations from interface references. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Interface referencing should probably check for a previous type declaration, but Wine IDLs currently have many places where this is broken. This is for instance the case when a coclass use the inner interface statement to declare an interface without any previous declaration. And in mimeole.idl, coclass are being declared with the same name as their interface, to generate the corresponding CLSID. Signed-off-by: RĂ©mi Bernon Signed-off-by: Jacek Caban Signed-off-by: Alexandre Julliard --- tools/widl/parser.y | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 5008a35f64f..1505e3e88a0 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -286,7 +286,8 @@ static typelib_t *current_typelib; %type type_qualifier m_type_qual_list %type function_specifier %type decl_spec decl_spec_no_type m_decl_spec_no_type -%type inherit interface interfacedef interfacedec +%type inherit interface interfacedef +%type interfaceref %type dispinterface dispinterfacehdr dispinterfacedef %type module modulehdr moduledef %type namespacedef @@ -356,7 +357,8 @@ m_acf: /* empty */ | aACF acf_statements gbl_statements: { $$ = NULL; } | gbl_statements namespacedef '{' { push_namespace($2); } gbl_statements '}' { pop_namespace($2); $$ = append_statements($1, $5); } - | gbl_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); } + | gbl_statements interface ';' { $$ = append_statement($1, make_statement_reference($2)); } + | gbl_statements dispinterface ';' { $$ = 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, current_namespace, 0); @@ -375,7 +377,8 @@ gbl_statements: { $$ = NULL; } ; imp_statements: { $$ = NULL; } - | imp_statements interfacedec { $$ = append_statement($1, make_statement_reference($2)); } + | imp_statements interface ';' { $$ = append_statement($1, make_statement_reference($2)); } + | imp_statements dispinterface ';' { $$ = append_statement($1, make_statement_reference($2)); } | imp_statements namespacedef '{' { push_namespace($2); } imp_statements '}' { pop_namespace($2); $$ = append_statements($1, $5); } | imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); } @@ -928,7 +931,7 @@ class_interfaces: { $$ = NULL; } ; class_interface: - m_attributes interfacedec { $$ = make_ifref($2); $$->attrs = $1; } + m_attributes interfaceref ';' { $$ = make_ifref($2); $$->attrs = $1; } ; dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } @@ -996,9 +999,11 @@ interfacedef: interfacehdr inherit | dispinterfacedef semicolon_opt { $$ = $1; } ; -interfacedec: - interface ';' { $$ = $1; } - | dispinterface ';' { $$ = $1; } +interfaceref: + tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } + | tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } + | tDISPINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } + | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); } ; module: tMODULE aIDENTIFIER { $$ = type_new_module($2); }