From 833639bd09a9df278a56553ced4b080699dc5313 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Mon, 19 Aug 2019 21:17:38 -0500 Subject: [PATCH] widl: Create exactly one type_t object per named union type. Based on a patch by Richard Pospesel. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- 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 9db8ebd6fc4..a52afc79219 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 05e96844d8c..a7fd561db84 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 7a7bd8991ec..5e283292785 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);