[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