Rémi Bernon : widl: Factor and cleanup interface type declaration and definition.

Alexandre Julliard julliard at winehq.org
Fri Feb 5 16:50:49 CST 2021


Module: wine
Branch: master
Commit: f8684cf953c5aae31e0b2858ab839e702b7cff20
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=f8684cf953c5aae31e0b2858ab839e702b7cff20

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Fri Feb  5 10:11:00 2021 +0100

widl: Factor and cleanup interface type declaration and definition.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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);




More information about the wine-cvs mailing list