widl: Create exactly one type_t object per named union type.
Based on a patch by Richard Pospesel. Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
42321d7a11
commit
833639bd09
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue