[PATCH 1/5] widl: Factor and cleanup interface type declaration and definition.

Rémi Bernon rbernon at codeweavers.com
Fri Feb 5 03:11:00 CST 2021


Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

I didn't factor enum/struct/union defs in the same way as these types
because their rules are a bit more convoluted and they don't use the
aKNOWNTYPE token, so it didn't seem useful to do so for the purpose of
this refactoring. Although it could be nice to do it for consistency.

 tools/widl/parser.y   | 34 ++++++++++------------------------
 tools/widl/typetree.c | 19 ++++++++++++++++++-
 tools/widl/typetree.h |  4 +++-
 3 files changed, 31 insertions(+), 26 deletions(-)

diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 1505e3e88a0..44716deb5b6 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -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;
 }
 
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 825348ddef4..84be75fa3b7 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -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)
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 8a8e1c529ac..7b67f3b996a 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -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);
-- 
2.30.0




More information about the wine-devel mailing list