Commit 1a71479f authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

widl: Create a separate type_t object for each structure declaration or defintion.

Set the details of the structure to the previously defined version if available, or add it to a list of incomplete types otherwise. Only set the defined flag when the structure is actually defined in the IDL file so that the type is written out in the exact order that it is mentioned in the file.
parent efdd0205
......@@ -97,6 +97,7 @@ typelist_t incomplete_types = LIST_INIT(incomplete_types);
static void add_incomplete(type_t *t);
static void fix_incomplete(void);
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);
......@@ -126,7 +127,7 @@ static typelib_t *make_library(const char *name, const attr_list_t *attrs);
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type);
static type_t *type_new_enum(char *name, var_list_t *enums);
static type_t *type_new_struct(char *name, var_list_t *fields);
static type_t *type_new_struct(char *name, int defined, var_list_t *fields);
static type_t *type_new_nonencapsulated_union(char *name, var_list_t *fields);
static type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
......@@ -1047,7 +1048,7 @@ pointer_type:
| tPTR { $$ = RPC_FC_FP; }
;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, $4);
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, TRUE, $4);
if(in_typelib)
add_typelib_entry($$);
}
......@@ -1059,7 +1060,7 @@ type: tVOID { $$ = find_type_or_error("void", 0); }
| enumdef { $$ = $1; }
| tENUM aIDENTIFIER { $$ = find_type_or_error2($2, tsENUM); }
| structdef { $$ = $1; }
| tSTRUCT aIDENTIFIER { $$ = get_type(RPC_FC_STRUCT, $2, tsSTRUCT); }
| tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, FALSE, NULL); }
| uniondef { $$ = $1; }
| tUNION aIDENTIFIER { $$ = find_type_or_error2($2, tsUNION); }
| tSAFEARRAY '(' type ')' { $$ = make_safearray($3); }
......@@ -1385,13 +1386,33 @@ static type_t *type_new_enum(char *name, var_list_t *enums)
return t;
}
static type_t *type_new_struct(char *name, var_list_t *fields)
static type_t *type_new_struct(char *name, int defined, var_list_t *fields)
{
type_t *t = get_type(RPC_FC_STRUCT, name, tsSTRUCT);
type_t *tag_type = name ? find_type(name, tsSTRUCT) : NULL;
type_t *t = make_type(RPC_FC_STRUCT, NULL);
t->name = name;
t->kind = TKIND_RECORD;
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
if (defined || (tag_type && tag_type->details.structure))
{
if (tag_type && tag_type->details.structure)
{
t->details.structure = tag_type->details.structure;
t->type = tag_type->type;
}
else if (defined)
{
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
}
}
if (name)
{
if (fields)
reg_type(t, name, tsSTRUCT);
else
add_incomplete(t);
}
return t;
}
......@@ -1807,6 +1828,8 @@ static type_t *reg_type(type_t *type, const char *name, int t)
nt->t = t;
nt->next = type_hash[hash];
type_hash[hash] = nt;
if ((t == tsSTRUCT || t == tsUNION))
fix_incomplete_types(type);
return type;
}
......@@ -1839,10 +1862,29 @@ static void fix_incomplete(void)
LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) {
fix_type(tn->type);
list_remove(&tn->entry);
free(tn);
}
}
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 (((is_struct(complete_type->type) && is_struct(tn->type->type)) ||
(is_union(complete_type->type) && is_union(tn->type->type))) &&
!strcmp(complete_type->name, tn->type->name))
{
tn->type->details.structure = complete_type->details.structure;
tn->type->type = complete_type->type;
list_remove(&tn->entry);
free(tn);
}
}
}
static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs)
{
const declarator_t *decl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment