widl: Fix incomplete struct/union typedef bug.

This commit is contained in:
Dan Hipschman 2007-06-07 17:43:58 -07:00 committed by Alexandre Julliard
parent b186c4dd0e
commit 4e22899e13
3 changed files with 54 additions and 3 deletions

View File

@ -65,6 +65,17 @@
# endif # endif
#endif #endif
typedef struct list typelist_t;
struct typenode {
type_t *type;
struct list entry;
};
typelist_t incomplete_types = LIST_INIT(incomplete_types);
static void add_incomplete(type_t *t);
static void fix_incomplete(void);
static str_list_t *append_str(str_list_t *list, char *str); 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(attr_list_t *list, attr_t *attr);
static attr_t *make_attr(enum attr_type type); static attr_t *make_attr(enum attr_type type);
@ -263,7 +274,11 @@ static void check_arg(var_t *arg);
%% %%
input: gbl_statements { write_proxies($1); write_client($1); write_server($1); } input: gbl_statements { fix_incomplete();
write_proxies($1);
write_client($1);
write_server($1);
}
; ;
gbl_statements: { $$ = NULL; } gbl_statements: { $$ = NULL; }
@ -1475,6 +1490,38 @@ static type_t *reg_type(type_t *type, const char *name, int t)
return type; return type;
} }
static int is_incomplete(const type_t *t)
{
return !t->defined && (is_struct(t->type) || is_union(t->type));
}
static 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_type(type_t *t)
{
if (t->kind == TKIND_ALIAS && is_incomplete(t)) {
type_t *ot = t->orig;
fix_type(ot);
t->fields = ot->fields;
t->defined = ot->defined;
}
}
static void fix_incomplete(void)
{
struct typenode *tn, *next;
LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry) {
fix_type(tn->type);
free(tn);
}
}
static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs)
{ {
type_t *ptr = type; type_t *ptr = type;
@ -1544,6 +1591,8 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
yyerror("'%s': [string] attribute applied to non-pointer type", yyerror("'%s': [string] attribute applied to non-pointer type",
cur->name); cur->name);
if (is_incomplete(cur))
add_incomplete(cur);
reg_type(cur, cur->name, 0); reg_type(cur, cur->name, 0);
} }
} }

View File

@ -109,7 +109,7 @@ const char *string_of_type(unsigned char type)
} }
} }
static int is_struct(unsigned char type) int is_struct(unsigned char type)
{ {
switch (type) switch (type)
{ {
@ -125,7 +125,7 @@ static int is_struct(unsigned char type)
} }
} }
static int is_union(unsigned char type) int is_union(unsigned char type)
{ {
switch (type) switch (type)
{ {

View File

@ -305,5 +305,7 @@ int is_ptr(const type_t *t);
int is_array(const type_t *t); int is_array(const type_t *t);
int is_var_ptr(const var_t *v); int is_var_ptr(const var_t *v);
int cant_be_null(const var_t *v); int cant_be_null(const var_t *v);
int is_struct(unsigned char tc);
int is_union(unsigned char tc);
#endif #endif