Commit 213f3274 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

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.
parent 04a22cc4
......@@ -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)
......
......@@ -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;
......
......@@ -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);
}
......@@ -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 */
......@@ -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;
......
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