[PATCH 3/4] widl: Create exactly one type_t object per named union type.

Zebediah Figura z.figura12 at gmail.com
Mon Aug 19 21:17:38 CDT 2019


Based on a patch by Richard Pospesel.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 tools/widl/parser.y    | 38 -------------------------
 tools/widl/typetree.c  | 63 +++++++++++++++++++++++++++---------------
 tools/widl/widltypes.h |  1 -
 3 files changed, 41 insertions(+), 61 deletions(-)

diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 9db8ebd6fc..a52afc7921 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -50,10 +50,6 @@ struct _import_t
   int import_performed;
 };
 
-typelist_t incomplete_types = LIST_INIT(incomplete_types);
-
-static void fix_incomplete_types(type_t *complete_type);
-
 static str_list_t *append_str(str_list_t *list, char *str);
 static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
 static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
@@ -1880,41 +1876,9 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
   nt->t = t;
   nt->next = namespace->type_hash[hash];
   namespace->type_hash[hash] = nt;
-  if ((t == tsUNION))
-    fix_incomplete_types(type);
   return type;
 }
 
-static int is_incomplete(const type_t *t)
-{
-  return !t->defined &&
-    (type_get_type_detect_alias(t) == TYPE_STRUCT ||
-     type_get_type_detect_alias(t) == TYPE_UNION ||
-     type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
-}
-
-void add_incomplete(type_t *t)
-{
-  struct typenode *tn = xmalloc(sizeof *tn);
-  tn->type = t;
-  list_add_tail(&incomplete_types, &tn->entry);
-}
-
-static void fix_incomplete_types(type_t *complete_type)
-{
-  struct typenode *tn, *next;
-
-  LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry)
-  {
-    if (type_is_equal(complete_type, tn->type))
-    {
-      tn->type->details.structure = complete_type->details.structure;
-      list_remove(&tn->entry);
-      free(tn);
-    }
-  }
-}
-
 static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs)
 {
   declarator_t *decl;
@@ -1966,8 +1930,6 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
       cur = type_new_alias(&name->declspec, name->name);
       cur->attrs = attrs;
 
-      if (is_incomplete(cur))
-        add_incomplete(cur);
       reg_type(cur, cur->name, current_namespace, 0);
     }
   }
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 05e96844d8..a7fd561db8 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -283,8 +283,6 @@ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined
     {
         if (defined)
             reg_type(t, name, namespace, tsENUM);
-        else
-            add_incomplete(t);
     }
     return t;
 }
@@ -317,36 +315,57 @@ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, va
 
 type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
 {
-    type_t *tag_type = name ? find_type(name, NULL, tsUNION) : NULL;
-    type_t *t = make_type(TYPE_UNION);
-    t->name = name;
-    if (tag_type && tag_type->details.structure)
-        t->details.structure = tag_type->details.structure;
-    else if (defined)
+    type_t *t = NULL;
+
+    if (name)
+        t = find_type(name, NULL, tsUNION);
+
+    if (!t)
+    {
+        t = make_type(TYPE_UNION);
+        t->name = name;
+        if (name)
+            reg_type(t, name, NULL, tsUNION);
+    }
+
+    if (!t->defined && defined)
     {
         t->details.structure = xmalloc(sizeof(*t->details.structure));
         t->details.structure->fields = fields;
         t->defined = TRUE;
     }
-    if (name)
-    {
-        if (defined)
-            reg_type(t, name, NULL, tsUNION);
-        else
-            add_incomplete(t);
-    }
+
     return t;
 }
 
 type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases)
 {
-    type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, NULL, tsUNION);
-    if (!union_field) union_field = make_var( xstrdup("tagged_union") );
-    union_field->declspec.type = type_new_nonencapsulated_union(NULL, TRUE, cases);
-    t->details.structure = xmalloc(sizeof(*t->details.structure));
-    t->details.structure->fields = append_var( NULL, switch_field );
-    t->details.structure->fields = append_var( t->details.structure->fields, union_field );
-    t->defined = TRUE;
+    type_t *t = NULL;
+
+    if (name)
+        t = find_type(name, NULL, tsUNION);
+
+    if (!t)
+    {
+        t = make_type(TYPE_ENCAPSULATED_UNION);
+        t->name = name;
+        if (name)
+            reg_type(t, name, NULL, tsUNION);
+    }
+    t->type_type = TYPE_ENCAPSULATED_UNION;
+
+    if (!t->defined)
+    {
+        if (!union_field)
+            union_field = make_var(xstrdup("tagged_union"));
+        union_field->declspec.type = type_new_nonencapsulated_union(NULL, TRUE, cases);
+
+        t->details.structure = xmalloc(sizeof(*t->details.structure));
+        t->details.structure->fields = append_var(NULL, switch_field);
+        t->details.structure->fields = append_var(t->details.structure->fields, union_field);
+        t->defined = TRUE;
+    }
+
     return t;
 }
 
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 7a7bd8991e..5e28329278 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -596,7 +596,6 @@ type_t *find_type(const char *name, struct namespace *namespace, int t);
 type_t *make_type(enum type_type type);
 type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t);
 type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, int t);
-void add_incomplete(type_t *t);
 
 var_t *make_var(char *name);
 var_list_t *append_var(var_list_t *list, var_t *var);
-- 
2.22.0




More information about the wine-devel mailing list