widl: Factor and cleanup interface type declaration and definition.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2021-02-05 10:11:00 +01:00 committed by Alexandre Julliard
parent d4156d1da8
commit f8684cf953
3 changed files with 31 additions and 26 deletions

View File

@ -87,7 +87,6 @@ static void push_lookup_namespace(const char *name);
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);
@ -281,7 +280,6 @@ static typelib_t *current_typelib;
%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 <expr> contract_req
%type <type> interfacehdr
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
%type <function_specifier> function_specifier
@ -971,31 +969,20 @@ inherit: { $$ = NULL; }
| ':' qualified_type { $$ = $2; }
;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
| tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
interface:
tINTERFACE aIDENTIFIER { $$ = type_interface_declare($2, current_namespace); }
| tINTERFACE aKNOWNTYPE { $$ = type_interface_declare($2, current_namespace); }
;
interfacehdr: attributes interface { $$ = $2;
check_def($2);
$2->attrs = check_iface_attrs($2->name, $1);
$2->defined = TRUE;
}
;
interfacedef: interfacehdr inherit
'{' int_statements '}' semicolon_opt { $$ = $1;
if($$ == $2)
error_loc("Interface can't inherit from itself\n");
type_interface_define($$, $2, $4);
interfacedef: attributes interface inherit
'{' int_statements '}' semicolon_opt { $$ = type_interface_define($2, $1, $3, $5);
check_async_uuid($$);
}
/* 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
| attributes interface ':' aIDENTIFIER
'{' import int_statements '}'
semicolon_opt { $$ = $1;
type_interface_define($$, find_type_or_error($3), $6);
}
semicolon_opt { $$ = type_interface_define($2, $1, find_type_or_error($4), $7); }
| dispinterfacedef semicolon_opt { $$ = $1; }
;
@ -2340,7 +2327,7 @@ const char *get_attr_display_name(enum attr_type type)
return allowed_attr[type].display_name;
}
static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs)
{
const attr_t *attr;
if (!attrs) return attrs;
@ -2978,8 +2965,7 @@ static void check_async_uuid(type_t *iface)
if (!inherit)
error_loc("async_uuid applied to an interface with incompatible parent\n");
async_iface = get_type(TYPE_INTERFACE, strmake("Async%s", iface->name), iface->namespace, 0);
async_iface->attrs = map_attrs(iface->attrs, async_iface_attrs);
async_iface = type_interface_declare(strmake("Async%s", iface->name), iface->namespace);
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
{
@ -3010,7 +2996,7 @@ static void check_async_uuid(type_t *iface)
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
type_interface_define(async_iface, inherit, stmts);
type_interface_define(async_iface, map_attrs(iface->attrs, async_iface_attrs), inherit, stmts);
iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface;
}

View File

@ -442,8 +442,24 @@ static unsigned int compute_method_indexes(type_t *iface)
return idx;
}
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
type_t *type_interface_declare(char *name, struct namespace *namespace)
{
type_t *type = get_type(TYPE_INTERFACE, name, namespace, 0);
if (type_get_type_detect_alias(type) != TYPE_INTERFACE)
error_loc("interface %s previously not declared an interface at %s:%d\n",
type->name, type->loc_info.input_name, type->loc_info.line_number);
return type;
}
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts)
{
if (iface->defined)
error_loc("interface %s already defined at %s:%d\n",
iface->name, iface->loc_info.input_name, iface->loc_info.line_number);
if (iface == inherit)
error_loc("interface %s can't inherit from itself\n",
iface->name);
iface->attrs = check_interface_attrs(iface->name, attrs);
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->details.iface->disp_props = NULL;
iface->details.iface->disp_methods = NULL;
@ -453,6 +469,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
iface->details.iface->async_iface = NULL;
iface->defined = TRUE;
compute_method_indexes(iface);
return iface;
}
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)

View File

@ -30,6 +30,7 @@ enum name_type {
};
attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs);
type_t *type_new_function(var_list_t *args);
@ -48,7 +49,8 @@ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_runtimeclass_declare(char *name, struct namespace *namespace);
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
type_t *type_interface_declare(char *name, struct namespace *namespace);
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts);
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts);