forked from Mirrors/wine-wine
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
parent
04a22cc412
commit
213f32744f
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue