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

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


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

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

widl: Factor and cleanup apicontract type declaration and definition.

And remove unused check_def helper.

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   | 35 +++++++++++++++--------------------
 tools/widl/typetree.c | 19 +++++++++++++++++++
 tools/widl/typetree.h |  3 +++
 3 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 349e4730d96..8c805e481f8 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -96,10 +96,8 @@ 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_module_attrs(const char *name, attr_list_t *attrs);
-static attr_list_t *check_apicontract_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 void check_async_uuid(type_t *iface);
 
@@ -305,7 +303,7 @@ static typelib_t *current_typelib;
 %type <declarator_list> declarator_list struct_declarator_list
 %type <type> coclass coclassdef
 %type <type> runtimeclass runtimeclass_def
-%type <type> apicontract
+%type <type> apicontract apicontract_def
 %type <num> contract_ver
 %type <num> pointer_type threading_type marshaling_behavior version
 %type <str> libraryhdr callconv cppquote importlib import t_ident
@@ -364,8 +362,9 @@ gbl_statements:					{ $$ = NULL; }
 	| gbl_statements coclassdef		{ $$ = append_statement($1, make_statement_type_decl($2));
 						  reg_type($2, $2->name, current_namespace, 0);
 						}
-	| gbl_statements apicontract ';'        { $$ = append_statement($1, make_statement_type_decl($2));
-	                                          reg_type($2, $2->name, current_namespace, 0); }
+	| gbl_statements apicontract ';'	{ $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
+	| gbl_statements apicontract_def	{ $$ = append_statement($1, make_statement_type_decl($2));
+						  reg_type($2, $2->name, current_namespace, 0); }
 	| gbl_statements runtimeclass ';'       { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
 	| gbl_statements runtimeclass_def       { $$ = append_statement($1, make_statement_type_decl($2));
 	                                          reg_type($2, $2->name, current_namespace, 0); }
@@ -384,8 +383,9 @@ imp_statements:					{ $$ = NULL; }
 	| imp_statements coclassdef		{ $$ = append_statement($1, make_statement_type_decl($2));
 						  reg_type($2, $2->name, current_namespace, 0);
 						}
-	| imp_statements apicontract ';'        { $$ = append_statement($1, make_statement_type_decl($2));
-	                                          reg_type($2, $2->name, current_namespace, 0); }
+	| imp_statements apicontract ';'	{ $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
+	| imp_statements apicontract_def	{ $$ = append_statement($1, make_statement_type_decl($2));
+						  reg_type($2, $2->name, current_namespace, 0); }
 	| imp_statements runtimeclass ';'       { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
 	| imp_statements runtimeclass_def       { $$ = append_statement($1, make_statement_type_decl($2));
 	                                          reg_type($2, $2->name, current_namespace, 0); }
@@ -913,11 +913,13 @@ runtimeclass_def: attributes runtimeclass '{' class_interfaces '}' semicolon_opt
 						{ $$ = type_runtimeclass_define($2, $1, $4); }
 	;
 
-apicontract: attributes tAPICONTRACT aIDENTIFIER '{' '}'
-						{ $$ = get_type(TYPE_APICONTRACT, $3, current_namespace, 0);
-						  check_def($$);
-						  $$->attrs = check_apicontract_attrs($$->name, $1);
-						}
+apicontract:
+	  tAPICONTRACT aIDENTIFIER		{ $$ = type_apicontract_declare($2, current_namespace); }
+	| tAPICONTRACT aKNOWNTYPE		{ $$ = type_apicontract_declare($2, current_namespace); }
+	;
+
+apicontract_def: attributes apicontract '{' '}' semicolon_opt
+						{ $$ = type_apicontract_define($2, $1); }
 	;
 
 namespacedef: tNAMESPACE aIDENTIFIER		{ $$ = $2; }
@@ -2511,7 +2513,7 @@ attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs)
     return attrs;
 }
 
-static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
+attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
 {
     const attr_t *attr;
     if (!attrs) return attrs;
@@ -3205,10 +3207,3 @@ void init_loc_info(loc_info_t *i)
     i->line_number = line_number;
     i->near_text = parser_text;
 }
-
-static void check_def(const type_t *t)
-{
-    if (t->defined)
-        error_loc("%s: redefinition error; original definition was at %s:%d\n",
-                  t->name, t->loc_info.input_name, t->loc_info.line_number);
-}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 81eaba5556b..004f7fc7b0d 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -569,6 +569,25 @@ type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref
     return runtimeclass;
 }
 
+type_t *type_apicontract_declare(char *name, struct namespace *namespace)
+{
+    type_t *type = get_type(TYPE_APICONTRACT, name, namespace, 0);
+    if (type_get_type_detect_alias(type) != TYPE_APICONTRACT)
+        error_loc("apicontract %s previously not declared a apicontract at %s:%d\n",
+                  type->name, type->loc_info.input_name, type->loc_info.line_number);
+    return type;
+}
+
+type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs)
+{
+    if (apicontract->defined)
+        error_loc("apicontract %s already defined at %s:%d\n",
+                  apicontract->name, apicontract->loc_info.input_name, apicontract->loc_info.line_number);
+    apicontract->attrs = check_apicontract_attrs(apicontract->name, attrs);
+    apicontract->defined = TRUE;
+    return apicontract;
+}
+
 int type_is_equal(const type_t *type1, const type_t *type2)
 {
     if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 280d2e722cf..7c19da8e045 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -29,6 +29,7 @@ enum name_type {
     NAME_C
 };
 
+attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
 attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
 attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
 attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
@@ -58,6 +59,8 @@ type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *att
 void type_module_define(type_t *module, statement_list_t *stmts);
 type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *ifaces);
 type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_list_t *ifaces);
+type_t *type_apicontract_declare(char *name, struct namespace *namespace);
+type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs);
 int type_is_equal(const type_t *type1, const type_t *type2);
 const char *type_get_name(const type_t *type, enum name_type name_type);
 char *gen_name(void);




More information about the wine-cvs mailing list