widl: Store the type-specific information in a union in the type_t structure.

Use pointers for the information for structures, enumerations,
functions and interfaces so that we can determine whether or not the
type has been defined yet and to enable more information to be stored.
oldstable
Rob Shearman 2008-12-29 12:05:35 +00:00 committed by Alexandre Julliard
parent 04a22cc412
commit 213f32744f
5 changed files with 91 additions and 31 deletions

View File

@ -411,7 +411,7 @@ void check_for_additional_prototype_types(const var_list_t *list)
* using a wire marshaled type */
break;
}
else
else if (type_is_complete(type))
{
var_list_t *vars = NULL;
if (type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32)

View File

@ -1351,7 +1351,7 @@ type_t *make_type(unsigned char type, type_t *ref)
t->attrs = NULL;
t->orig = NULL;
t->funcs = NULL;
t->fields_or_args = NULL;
memset(&t->details, 0, sizeof(t->details));
t->ifaces = NULL;
t->dim = 0;
t->size_is = NULL;
@ -1375,7 +1375,13 @@ static type_t *type_new_enum(var_t *name, var_list_t *enums)
{
type_t *t = get_typev(RPC_FC_ENUM16, name, tsENUM);
t->kind = TKIND_ENUM;
t->fields_or_args = enums;
if (enums)
{
t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
t->details.enumeration->enums = enums;
}
else
t->details.enumeration = NULL;
t->defined = TRUE;
return t;
}
@ -1384,7 +1390,8 @@ static type_t *type_new_struct(var_t *name, var_list_t *fields)
{
type_t *t = get_typev(RPC_FC_STRUCT, name, tsSTRUCT);
t->kind = TKIND_RECORD;
t->fields_or_args = fields;
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
return t;
}
@ -1393,7 +1400,8 @@ static type_t *type_new_nonencapsulated_union(var_t *name, var_list_t *fields)
{
type_t *t = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, name, tsUNION);
t->kind = TKIND_UNION;
t->fields_or_args = fields;
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
t->defined = TRUE;
return t;
}
@ -1405,23 +1413,25 @@ static type_t *type_new_encapsulated_union(var_t *name, var_t *switch_field, var
if (!union_field) union_field = make_var( xstrdup("tagged_union") );
union_field->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL);
union_field->type->kind = TKIND_UNION;
union_field->type->fields_or_args = cases;
union_field->type->details.structure = xmalloc(sizeof(*union_field->type->details.structure));
union_field->type->details.structure->fields = cases;
union_field->type->defined = TRUE;
t->fields_or_args = append_var( NULL, switch_field );
t->fields_or_args = append_var( t->fields_or_args, union_field );
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;
}
static void function_add_head_arg(func_t *func, var_t *arg)
{
if (!func->def->type->fields_or_args)
if (!func->def->type->details.function->args)
{
func->def->type->fields_or_args = xmalloc( sizeof(*func->def->type->fields_or_args) );
list_init( func->def->type->fields_or_args );
func->def->type->details.function->args = xmalloc( sizeof(*func->def->type->details.function->args) );
list_init( func->def->type->details.function->args );
}
list_add_head( func->def->type->fields_or_args, &arg->entry );
func->args = func->def->type->fields_or_args;
list_add_head( func->def->type->details.function->args, &arg->entry );
func->args = func->def->type->details.function->args;
}
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
@ -1726,7 +1736,7 @@ static func_t *make_func(var_t *def)
{
func_t *f = xmalloc(sizeof(func_t));
f->def = def;
f->args = def->type->fields_or_args;
f->args = def->type->details.function->args;
f->ignore = parse_only;
f->idx = -1;
return f;
@ -1818,7 +1828,8 @@ 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_or_args = ot->fields_or_args;
if (is_struct(ot->type) || is_union(ot->type))
t->details.structure = ot->details.structure;
t->defined = ot->defined;
}
}
@ -2469,7 +2480,7 @@ static void check_remoting_fields(const var_t *var, type_t *type)
if (is_struct(type->type))
{
if (type_is_defined(type))
if (type_is_complete(type))
fields = type_struct_get_fields(type);
else
error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
@ -2581,7 +2592,8 @@ static void check_all_user_types(const statement_list_t *stmts)
{
if (stmt->type == STMT_LIBRARY)
check_all_user_types(stmt->u.lib->stmts);
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP &&
!is_local(stmt->u.type->attrs))
{
const func_t *f;
const func_list_t *fs = stmt->u.type->funcs;

View File

@ -32,7 +32,8 @@
type_t *type_new_function(var_list_t *args)
{
type_t *t = make_type(RPC_FC_FUNCTION, NULL);
t->fields_or_args = args;
t->details.function = xmalloc(sizeof(*t->details.function));
t->details.function->args = args;
return t;
}
@ -66,7 +67,10 @@ static int compute_method_indexes(type_t *iface)
void type_interface_define(type_t *iface, type_t *inherit, func_list_t *funcs)
{
iface->ref = inherit;
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->funcs = funcs;
iface->details.iface->disp_props = NULL;
iface->details.iface->disp_methods = NULL;
iface->defined = TRUE;
check_functions(iface);
compute_method_indexes(iface);
@ -76,8 +80,10 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *me
{
iface->ref = find_type("IDispatch", 0);
if (!iface->ref) error_loc("IDispatch is undefined\n");
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->funcs = NULL;
iface->fields_or_args = props;
iface->details.iface->disp_props = props;
iface->details.iface->disp_methods = methods;
iface->funcs = methods;
iface->defined = TRUE;
check_functions(iface);
@ -86,5 +92,6 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *me
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
{
type_dispinterface_define(dispiface, iface->fields_or_args, iface->funcs);
type_dispinterface_define(dispiface, iface->details.iface->disp_props,
iface->details.iface->disp_methods);
}

View File

@ -33,31 +33,31 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
static inline var_list_t *type_struct_get_fields(const type_t *type)
{
assert(is_struct(type->type));
return type->fields_or_args;
return type->details.structure->fields;
}
static inline var_list_t *type_function_get_args(const type_t *type)
{
assert(type->type == RPC_FC_FUNCTION);
return type->fields_or_args;
return type->details.function->args;
}
static inline var_list_t *type_enum_get_values(const type_t *type)
{
assert(type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32);
return type->fields_or_args;
return type->details.enumeration->enums;
}
static inline var_t *type_union_get_switch_value(const type_t *type)
{
assert(type->type == RPC_FC_ENCAPSULATED_UNION);
return LIST_ENTRY(list_head(type->fields_or_args), var_t, entry);
return LIST_ENTRY(list_head(type->details.structure->fields), var_t, entry);
}
static inline var_list_t *type_encapsulated_union_get_fields(const type_t *type)
{
assert(type->type == RPC_FC_ENCAPSULATED_UNION);
return type->fields_or_args;
return type->details.structure->fields;
}
static inline var_list_t *type_union_get_cases(const type_t *type)
@ -66,23 +66,23 @@ static inline var_list_t *type_union_get_cases(const type_t *type)
type->type == RPC_FC_NON_ENCAPSULATED_UNION);
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
return uv->type->fields_or_args;
const var_t *uv = LIST_ENTRY(list_tail(type->details.structure->fields), const var_t, entry);
return uv->type->details.structure->fields;
}
else
return type->fields_or_args;
return type->details.structure->fields;
}
static inline var_list_t *type_dispiface_get_props(const type_t *type)
{
assert(type->type == RPC_FC_IP);
return type->fields_or_args;
return type->details.iface->disp_props;
}
static inline var_list_t *type_dispiface_get_methods(const type_t *type)
{
assert(type->type == RPC_FC_IP);
return type->funcs;
return type->details.iface->disp_methods;
}
static inline int type_is_defined(const type_t *type)
@ -90,4 +90,18 @@ static inline int type_is_defined(const type_t *type)
return type->defined;
}
static inline int type_is_complete(const type_t *type)
{
if (type->type == RPC_FC_FUNCTION)
return (type->details.function != NULL);
else if (type->type == RPC_FC_IP)
return (type->details.iface != NULL);
else if (type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32)
return (type->details.enumeration != NULL);
else if (is_struct(type->type) || is_union(type->type))
return (type->details.structure != NULL);
else
return TRUE;
}
#endif /* WIDL_TYPE_TREE_H */

View File

@ -260,14 +260,41 @@ struct _expr_t {
struct list entry;
};
struct struct_details
{
var_list_t *fields;
};
struct enumeration_details
{
var_list_t *enums;
};
struct func_details
{
var_list_t *args;
};
struct iface_details
{
func_list_t *disp_methods;
var_list_t *disp_props;
};
struct _type_t {
const char *name;
enum type_kind kind;
unsigned char type;
struct _type_t *ref;
attr_list_t *attrs;
union
{
struct struct_details *structure;
struct enumeration_details *enumeration;
struct func_details *function;
struct iface_details *iface;
} details;
func_list_t *funcs; /* interfaces and modules */
var_list_t *fields_or_args; /* interfaces, structures, enumerations and functions (for args) */
ifref_list_t *ifaces; /* coclasses */
unsigned long dim; /* array dimension */
expr_t *size_is, *length_is;