widl: Hide the details of where arguments, fields, values and cases are stored in the type_t structure for functions, structures, enums and unions.

This commit is contained in:
Rob Shearman 2008-12-29 12:05:27 +00:00 committed by Alexandre Julliard
parent fbffe4a229
commit 04a22cc412
10 changed files with 325 additions and 163 deletions

View file

@ -17,6 +17,7 @@ C_SRCS = \
server.c \
typegen.c \
typelib.c \
typetree.c \
utils.c \
widl.c \
write_msft.c

View file

@ -32,6 +32,7 @@
#include "utils.h"
#include "expr.h"
#include "header.h"
#include "typetree.h"
expr_t *make_expr(enum expr_type type)
{
@ -362,17 +363,14 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
*found_in_cont_type = 0;
if (cont_type && (cont_type->type == RPC_FC_FUNCTION || is_struct(cont_type->type)))
fields = cont_type->fields_or_args;
else if (cont_type && is_union(cont_type->type))
if (cont_type)
{
if (cont_type->type == RPC_FC_ENCAPSULATED_UNION)
{
const var_t *uv = LIST_ENTRY(list_tail(cont_type->fields_or_args), const var_t, entry);
fields = uv->type->fields_or_args;
}
else
fields = cont_type->fields_or_args;
if (cont_type->type == RPC_FC_FUNCTION)
fields = type_function_get_args(cont_type);
else if (is_struct(cont_type->type))
fields = type_struct_get_fields(cont_type);
else if (is_union(cont_type->type))
fields = type_union_get_cases(cont_type);
}
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )

View file

@ -34,6 +34,7 @@
#include "parser.h"
#include "header.h"
#include "expr.h"
#include "typetree.h"
typedef struct _user_type_t generic_handle_t;
@ -209,7 +210,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "enum {\n");
t->written = TRUE;
indentation++;
write_enums(h, t->fields_or_args);
write_enums(h, type_enum_get_values(t));
indent(h, -1);
fprintf(h, "}");
}
@ -227,7 +228,10 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "struct {\n");
t->written = TRUE;
indentation++;
write_fields(h, t->fields_or_args);
if (t->type == RPC_FC_ENCAPSULATED_UNION)
write_fields(h, type_encapsulated_union_get_fields(t));
else
write_fields(h, type_struct_get_fields(t));
indent(h, -1);
fprintf(h, "}");
}
@ -239,7 +243,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "union {\n");
t->written = TRUE;
indentation++;
write_fields(h, t->fields_or_args);
write_fields(h, type_union_get_cases(t));
indent(h, -1);
fprintf(h, "}");
}
@ -308,7 +312,7 @@ void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
if (pt->type == RPC_FC_FUNCTION) {
if (ptr_level) fputc(')', h);
fputc('(', h);
write_args(h, pt->fields_or_args, NULL, 0, FALSE);
write_args(h, type_function_get_args(pt), NULL, 0, FALSE);
fputc(')', h);
} else
write_type_right(h, t, is_field);
@ -409,7 +413,14 @@ void check_for_additional_prototype_types(const var_list_t *list)
}
else
{
check_for_additional_prototype_types(type->fields_or_args);
var_list_t *vars = NULL;
if (type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32)
vars = type_enum_get_values(type);
else if (is_struct(type->type))
vars = type_struct_get_fields(type);
else if (is_union(type->type))
vars = type_union_get_cases(type);
check_for_additional_prototype_types(vars);
}
}
}

View file

@ -45,4 +45,6 @@ void pop_import(void);
int is_type(const char *name);
void check_functions(const type_t *iface);
#endif

View file

@ -39,6 +39,7 @@
#include "typelib.h"
#include "typegen.h"
#include "expr.h"
#include "typetree.h"
#if defined(YYBYACC)
/* Berkeley yacc (byacc) doesn't seem to know about these */
@ -122,10 +123,13 @@ static type_t *make_safearray(type_t *type);
static type_t *make_builtin(char *name);
static type_t *make_int(int sign);
static typelib_t *make_library(const char *name, const attr_list_t *attrs);
static type_t *make_func_type(var_list_t *args);
static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs);
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type);
static type_t *type_new_enum(var_t *name, var_list_t *enums);
static type_t *type_new_struct(var_t *name, var_list_t *fields);
static type_t *type_new_nonencapsulated_union(var_t *name, var_list_t *fields);
static type_t *type_new_encapsulated_union(var_t *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
static type_t *reg_type(type_t *type, const char *name, int t);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
static type_t *find_type_or_error(const char *name, int t);
@ -140,11 +144,9 @@ static void write_clsid(type_t *cls);
static void write_diid(type_t *iface);
static void write_iid(type_t *iface);
static int compute_method_indexes(type_t *iface);
static char *gen_name(void);
static statement_t *process_typedefs(var_list_t *names);
static void check_arg(var_t *arg);
static void check_functions(const type_t *iface);
static void check_all_user_types(const statement_list_t *stmts);
static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
@ -642,10 +644,7 @@ enum: ident '=' expr_int_const { $$ = reg_const($1);
}
;
enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM);
$$->kind = TKIND_ENUM;
$$->fields_or_args = $4;
$$->defined = TRUE;
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, $4);
if(in_typelib)
add_typelib_entry($$);
}
@ -886,8 +885,6 @@ dispinterfacehdr: attributes dispinterface { attr_t *attrs;
check_def($$);
attrs = make_attr(ATTR_DISPINTERFACE);
$$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
$$->ref = find_type("IDispatch", 0);
if (!$$->ref) error_loc("IDispatch is undefined\n");
$$->defined = TRUE;
if (!parse_only && do_header) write_forward($$);
}
@ -905,16 +902,14 @@ dispinterfacedef: dispinterfacehdr '{'
dispint_props
dispint_meths
'}' { $$ = $1;
$$->fields_or_args = $3;
$$->funcs = $4;
type_dispinterface_define($$, $3, $4);
if (!parse_only && do_header) write_interface($$);
if (!parse_only && do_idfile) write_diid($$);
is_in_interface = FALSE;
}
| dispinterfacehdr
'{' interface ';' '}' { $$ = $1;
$$->fields_or_args = $3->fields_or_args;
$$->funcs = $3->funcs;
type_dispinterface_define_from_iface($$, $3);
if (!parse_only && do_header) write_interface($$);
if (!parse_only && do_idfile) write_diid($$);
is_in_interface = FALSE;
@ -944,10 +939,7 @@ interfacehdr: attributes interface { $$.interface = $2;
interfacedef: interfacehdr inherit
'{' int_statements '}' semicolon_opt { $$ = $1.interface;
$$->ref = $2;
$$->funcs = $4;
check_functions($$);
compute_method_indexes($$);
type_interface_define($$, $2, $4);
if (!parse_only && do_header) write_interface($$);
if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
if (!parse_only && do_idfile) write_iid($$);
@ -959,10 +951,7 @@ interfacedef: interfacehdr inherit
| interfacehdr ':' aIDENTIFIER
'{' import int_statements '}'
semicolon_opt { $$ = $1.interface;
$$->ref = find_type_or_error2($3, 0);
if (!$$->ref) error_loc("base class '%s' not found in import\n", $3);
$$->funcs = $6;
compute_method_indexes($$);
type_interface_define($$, find_type_or_error2($3, 0), $6);
if (!parse_only && do_header) write_interface($$);
if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
if (!parse_only && do_idfile) write_iid($$);
@ -1028,7 +1017,7 @@ decl_spec_no_type:
declarator:
'*' m_type_qual_list declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, make_pointer_type(NULL, $2)); }
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(NULL, $2)); }
| callconv declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| direct_declarator
;
@ -1038,7 +1027,7 @@ direct_declarator:
| '(' declarator ')' { $$ = $2; }
| direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); }
| direct_declarator '(' m_args ')' { $$ = $1;
$$->func_type = append_ptrchain_type($$->type, make_func_type($3));
$$->func_type = append_ptrchain_type($$->type, type_new_function($3));
$$->type = NULL;
}
;
@ -1059,11 +1048,7 @@ pointer_type:
| tPTR { $$ = RPC_FC_FP; }
;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT);
check_def($$);
$$->kind = TKIND_RECORD;
$$->fields_or_args = $4;
$$->defined = TRUE;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, $4);
if(in_typelib)
add_typelib_entry($$);
}
@ -1088,27 +1073,10 @@ typedef: tTYPEDEF m_attributes decl_spec declarator_list
;
uniondef: tUNION t_ident '{' ne_union_fields '}'
{ $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION);
check_def($$);
$$->kind = TKIND_UNION;
$$->fields_or_args = $4;
$$->defined = TRUE;
}
{ $$ = type_new_nonencapsulated_union($2, $4); }
| tUNION t_ident
tSWITCH '(' s_field ')'
m_ident '{' cases '}' { var_t *u = $7;
$$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION);
check_def($$);
$$->kind = TKIND_UNION;
if (!u) u = make_var( xstrdup("tagged_union") );
u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL);
u->type->kind = TKIND_UNION;
u->type->fields_or_args = $9;
u->type->defined = TRUE;
$$->fields_or_args = append_var( $$->fields_or_args, $5 );
$$->fields_or_args = append_var( $$->fields_or_args, u );
$$->defined = TRUE;
}
m_ident '{' cases '}' { $$ = type_new_encapsulated_union($2, $5, $7, $9); }
;
version:
@ -1403,18 +1371,57 @@ type_t *make_type(unsigned char type, type_t *ref)
return t;
}
static type_t *make_func_type(var_list_t *args)
static type_t *type_new_enum(var_t *name, var_list_t *enums)
{
type_t *t = make_type(RPC_FC_FUNCTION, NULL);
t->fields_or_args = args;
type_t *t = get_typev(RPC_FC_ENUM16, name, tsENUM);
t->kind = TKIND_ENUM;
t->fields_or_args = enums;
t->defined = TRUE;
return t;
}
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->defined = TRUE;
return t;
}
static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs)
static type_t *type_new_nonencapsulated_union(var_t *name, var_list_t *fields)
{
type_t *t = make_type(pointer_default, ref);
t->attrs = attrs;
return t;
type_t *t = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, name, tsUNION);
t->kind = TKIND_UNION;
t->fields_or_args = fields;
t->defined = TRUE;
return t;
}
static type_t *type_new_encapsulated_union(var_t *name, var_t *switch_field, var_t *union_field, var_list_t *cases)
{
type_t *t = get_typev(RPC_FC_ENCAPSULATED_UNION, name, tsUNION);
t->kind = TKIND_UNION;
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->defined = TRUE;
t->fields_or_args = append_var( NULL, switch_field );
t->fields_or_args = append_var( t->fields_or_args, 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)
{
func->def->type->fields_or_args = xmalloc( sizeof(*func->def->type->fields_or_args) );
list_init( func->def->type->fields_or_args );
}
list_add_head( func->def->type->fields_or_args, &arg->entry );
func->args = func->def->type->fields_or_args;
}
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
@ -2008,26 +2015,6 @@ static void write_iid(type_t *iface)
write_guid(idfile, "IID", iface->name, uuid);
}
static int compute_method_indexes(type_t *iface)
{
int idx;
func_t *f;
if (iface->ref)
idx = compute_method_indexes(iface->ref);
else
idx = 0;
if (!iface->funcs)
return idx;
LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry )
if (! is_callas(f->def->attrs))
f->idx = idx++;
return idx;
}
static char *gen_name(void)
{
static const char format[] = "__WIDL_%s_generated_name_%08lX";
@ -2482,21 +2469,13 @@ static void check_remoting_fields(const var_t *var, type_t *type)
if (is_struct(type->type))
{
if (type->defined)
fields = type->fields_or_args;
if (type_is_defined(type))
fields = type_struct_get_fields(type);
else
error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
}
else if (is_union(type->type))
{
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
fields = uv->type->fields_or_args;
}
else
fields = type->fields_or_args;
}
fields = type_union_get_cases(type);
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
if (field->type) check_field_common(type, type->name, field);
@ -2569,19 +2548,13 @@ static void add_explicit_handle_if_necessary(func_t *func)
var_t *idl_handle = make_var(xstrdup("IDL_handle"));
idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
idl_handle->type = find_type_or_error("handle_t", 0);
if (!func->def->type->fields_or_args)
{
func->def->type->fields_or_args = xmalloc( sizeof(*func->def->type->fields_or_args) );
list_init( func->def->type->fields_or_args );
}
list_add_head( func->def->type->fields_or_args, &idl_handle->entry );
func->args = func->def->type->fields_or_args;
function_add_head_arg(func, idl_handle);
}
}
}
}
static void check_functions(const type_t *iface)
void check_functions(const type_t *iface)
{
if (is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE) && iface->funcs)
{

View file

@ -36,7 +36,7 @@
#include "utils.h"
#include "parser.h"
#include "header.h"
#include "wine/list.h"
#include "typetree.h"
#include "typegen.h"
#include "expr.h"
@ -126,13 +126,16 @@ static int get_struct_type(const type_t *type)
int has_conformance = 0;
int has_variance = 0;
var_t *field;
var_list_t *fields;
if (type->type != RPC_FC_STRUCT) return type->type;
if (get_padding(type->fields_or_args))
fields = type_struct_get_fields(type);
if (get_padding(fields))
return RPC_FC_BOGUS_STRUCT;
if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, var_t, entry )
if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry )
{
type_t *t = field->type;
@ -174,7 +177,7 @@ static int get_struct_type(const type_t *type)
if (is_conformant_array(field->type))
{
has_conformance = 1;
if (field->type->declarray && list_next(type->fields_or_args, &field->entry))
if (field->type->declarray && list_next(fields, &field->entry))
error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n",
field->name);
}
@ -247,7 +250,7 @@ static int get_struct_type(const type_t *type)
case RPC_FC_CPSTRUCT:
has_conformance = 1;
if (list_next( type->fields_or_args, &field->entry ))
if (list_next( fields, &field->entry ))
error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n",
field->name);
has_pointer = 1;
@ -255,7 +258,7 @@ static int get_struct_type(const type_t *type)
case RPC_FC_CSTRUCT:
has_conformance = 1;
if (list_next( type->fields_or_args, &field->entry ))
if (list_next( fields, &field->entry ))
error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n",
field->name);
break;
@ -378,8 +381,9 @@ static int type_has_pointers(const type_t *type)
return type_has_pointers(type->ref);
else if (is_struct(type->type))
{
var_list_t *fields = type_struct_get_fields(type);
const var_t *field;
if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{
if (type_has_pointers(field->type))
return TRUE;
@ -389,13 +393,7 @@ static int type_has_pointers(const type_t *type)
{
var_list_t *fields;
const var_t *field;
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
fields = uv->type->fields_or_args;
}
else
fields = type->fields_or_args;
fields = type_union_get_cases(type);
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{
if (field->type && type_has_pointers(field->type))
@ -418,8 +416,9 @@ static int type_has_full_pointer(const type_t *type)
return type_has_full_pointer(type->ref);
else if (is_struct(type->type))
{
var_list_t *fields = type_struct_get_fields(type);
const var_t *field;
if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{
if (type_has_full_pointer(field->type))
return TRUE;
@ -429,13 +428,7 @@ static int type_has_full_pointer(const type_t *type)
{
var_list_t *fields;
const var_t *field;
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
fields = uv->type->fields_or_args;
}
else
fields = type->fields_or_args;
fields = type_union_get_cases(type);
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{
if (field->type && type_has_full_pointer(field->type))
@ -861,8 +854,9 @@ static size_t write_conf_or_var_desc(FILE *file, const type_t *structure,
unsigned char param_type = 0;
size_t offset = 0;
const var_t *var;
var_list_t *fields = type_struct_get_fields(structure);
if (structure->fields_or_args) LIST_FOR_EACH_ENTRY( var, structure->fields_or_args, const var_t, entry )
if (fields) LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
{
unsigned int align = 0;
/* FIXME: take alignment into account */
@ -1073,11 +1067,13 @@ size_t type_memsize(const type_t *t, unsigned int *align)
case RPC_FC_CSTRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_BOGUS_STRUCT:
size = fields_memsize(t->fields_or_args, align);
size = fields_memsize(type_struct_get_fields(t), align);
break;
case RPC_FC_ENCAPSULATED_UNION:
size = fields_memsize(type_encapsulated_union_get_fields(t), align);
break;
case RPC_FC_NON_ENCAPSULATED_UNION:
size = union_memsize(t->fields_or_args, align);
size = union_memsize(type_union_get_cases(t), align);
break;
case RPC_FC_SMFARRAY:
case RPC_FC_LGFARRAY:
@ -1295,7 +1291,7 @@ static void write_end(FILE *file, unsigned int *tfsoff)
static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
{
unsigned int offset = 0;
var_list_t *fs = type->fields_or_args;
var_list_t *fs = type_struct_get_fields(type);
var_t *f;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry)
@ -1372,7 +1368,7 @@ static int write_no_repeat_pointer_descriptions(
if (is_non_complex_struct(type))
{
const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry )
{
if (offset_in_memory && offset_in_buffer)
{
@ -1450,7 +1446,7 @@ static int write_pointer_description_offsets(
{
/* otherwise search for interesting fields to parse */
const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry )
{
if (offset_in_memory && offset_in_buffer)
{
@ -1526,7 +1522,7 @@ static int write_fixed_array_pointer_descriptions(
else if (is_struct(type->type))
{
const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry )
{
if (offset_in_memory && offset_in_buffer)
{
@ -1645,7 +1641,7 @@ static int write_varying_array_pointer_descriptions(
else if (is_struct(type->type))
{
const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry )
{
if (offset_in_memory && offset_in_buffer)
{
@ -1938,14 +1934,15 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
static const var_t *find_array_or_string_in_struct(const type_t *type)
{
const var_list_t *fields = type_struct_get_fields(type);
const var_t *last_field;
const type_t *ft;
int real_type;
if (!type->fields_or_args || list_empty(type->fields_or_args))
if (!fields || list_empty(fields))
return NULL;
last_field = LIST_ENTRY( list_tail(type->fields_or_args), const var_t, entry );
last_field = LIST_ENTRY( list_tail(fields), const var_t, entry );
ft = last_field->type;
if (ft->declarray && is_conformant_array(ft))
@ -1965,8 +1962,9 @@ static void write_struct_members(FILE *file, const type_t *type,
unsigned short offset = 0;
int salign = -1;
int padding;
var_list_t *fields = type_struct_get_fields(type);
if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{
type_t *ft = field->type;
if (!ft->declarray || !is_conformant_array(ft))
@ -2024,6 +2022,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
unsigned int corroff;
var_t *f;
int real_type = get_struct_type( type );
var_list_t *fields = type_struct_get_fields(type);
guard_rec(type);
current_structure = type;
@ -2033,7 +2032,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
error("structure size for %s exceeds %d bytes by %d bytes\n",
name, USHRT_MAX, total_size - USHRT_MAX);
if (type->fields_or_args) LIST_FOR_EACH_ENTRY(f, type->fields_or_args, var_t, entry)
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
has_pointers |= write_embedded_types(file, f->attrs, f->type, f->name,
FALSE, tfsoff);
if (!has_pointers) has_pointers = type_has_pointers(type);
@ -2098,11 +2097,10 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
if (real_type == RPC_FC_BOGUS_STRUCT)
{
const var_list_t *fs = type->fields_or_args;
const var_t *f;
type->ptrdesc = *tfsoff;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, const var_t, entry)
if (fields) LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
{
type_t *ft = f->type;
if (is_ptr(ft))
@ -2206,13 +2204,7 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
guard_rec(type);
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
fields = uv->type->fields_or_args;
}
else
fields = type->fields_or_args;
fields = type_union_get_cases(type);
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
{
@ -2228,7 +2220,7 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
print_start_tfs_comment(file, type, start_offset);
if (type->type == RPC_FC_ENCAPSULATED_UNION)
{
const var_t *sv = LIST_ENTRY(list_head(type->fields_or_args), const var_t, entry);
const var_t *sv = type_union_get_switch_value(type);
const type_t *st = sv->type;
switch (st->type)
@ -2720,8 +2712,8 @@ static unsigned int get_required_buffer_size_type(
return 0;
case RPC_FC_STRUCT:
if (!type->fields_or_args) return 0;
return fields_memsize(type->fields_or_args, alignment);
if (!type_struct_get_fields(type)) return 0;
return fields_memsize(type_struct_get_fields(type), alignment);
case RPC_FC_RP:
return

90
tools/widl/typetree.c Normal file
View file

@ -0,0 +1,90 @@
/*
* IDL Type Tree
*
* Copyright 2008 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include "widl.h"
#include "utils.h"
#include "parser.h"
#include "typetree.h"
#include "header.h"
type_t *type_new_function(var_list_t *args)
{
type_t *t = make_type(RPC_FC_FUNCTION, NULL);
t->fields_or_args = args;
return t;
}
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs)
{
type_t *t = make_type(pointer_default, ref);
t->attrs = attrs;
return t;
}
static int compute_method_indexes(type_t *iface)
{
int idx;
func_t *f;
if (iface->ref)
idx = compute_method_indexes(iface->ref);
else
idx = 0;
if (!iface->funcs)
return idx;
LIST_FOR_EACH_ENTRY( f, iface->funcs, func_t, entry )
if (! is_callas(f->def->attrs))
f->idx = idx++;
return idx;
}
void type_interface_define(type_t *iface, type_t *inherit, func_list_t *funcs)
{
iface->ref = inherit;
iface->funcs = funcs;
iface->defined = TRUE;
check_functions(iface);
compute_method_indexes(iface);
}
void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods)
{
iface->ref = find_type("IDispatch", 0);
if (!iface->ref) error_loc("IDispatch is undefined\n");
iface->funcs = NULL;
iface->fields_or_args = props;
iface->funcs = methods;
iface->defined = TRUE;
check_functions(iface);
compute_method_indexes(iface);
}
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
{
type_dispinterface_define(dispiface, iface->fields_or_args, iface->funcs);
}

93
tools/widl/typetree.h Normal file
View file

@ -0,0 +1,93 @@
/*
* IDL Type Tree
*
* Copyright 2008 Robert Shearman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "widltypes.h"
#include <assert.h>
#ifndef WIDL_TYPE_TREE_H
#define WIDL_TYPE_TREE_H
type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs);
void type_interface_define(type_t *iface, type_t *inherit, func_list_t *funcs);
void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods);
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;
}
static inline var_list_t *type_function_get_args(const type_t *type)
{
assert(type->type == RPC_FC_FUNCTION);
return type->fields_or_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;
}
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);
}
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;
}
static inline var_list_t *type_union_get_cases(const type_t *type)
{
assert(type->type == RPC_FC_ENCAPSULATED_UNION ||
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;
}
else
return type->fields_or_args;
}
static inline var_list_t *type_dispiface_get_props(const type_t *type)
{
assert(type->type == RPC_FC_IP);
return type->fields_or_args;
}
static inline var_list_t *type_dispiface_get_methods(const type_t *type)
{
assert(type->type == RPC_FC_IP);
return type->funcs;
}
static inline int type_is_defined(const type_t *type)
{
return type->defined;
}
#endif /* WIDL_TYPE_TREE_H */

View file

@ -22,6 +22,7 @@
#define __WIDL_WIDLTYPES_H
#include <stdarg.h>
#include <assert.h>
#include "guiddef.h"
#include "wine/rpcfc.h"
#include "wine/list.h"

View file

@ -51,6 +51,7 @@
#include "utils.h"
#include "header.h"
#include "hash.h"
#include "typetree.h"
enum MSFT_segment_index {
MSFT_SEG_TYPEINFO = 0, /* type information */
@ -1968,14 +1969,14 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
if (dispinterface->funcs)
LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) idx++;
if (dispinterface->fields_or_args)
LIST_FOR_EACH_ENTRY( var, dispinterface->fields_or_args, var_t, entry )
if (type_dispiface_get_props(dispinterface))
LIST_FOR_EACH_ENTRY( var, type_dispiface_get_props(dispinterface), var_t, entry )
add_var_desc(msft_typeinfo, idx++, var);
if (dispinterface->funcs)
if (type_dispiface_get_methods(dispinterface))
{
idx = 0;
LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry )
LIST_FOR_EACH_ENTRY( func, type_dispiface_get_methods(dispinterface), const func_t, entry )
if(add_func_desc(msft_typeinfo, func, idx) == S_OK)
idx++;
}
@ -2052,8 +2053,8 @@ static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure)
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs);
msft_typeinfo->typeinfo->size = 0;
if (structure->fields_or_args)
LIST_FOR_EACH_ENTRY( cur, structure->fields_or_args, var_t, entry )
if (type_struct_get_fields(structure))
LIST_FOR_EACH_ENTRY( cur, type_struct_get_fields(structure), var_t, entry )
add_var_desc(msft_typeinfo, idx++, cur);
}
@ -2067,8 +2068,8 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration)
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs);
msft_typeinfo->typeinfo->size = 0;
if (enumeration->fields_or_args)
LIST_FOR_EACH_ENTRY( cur, enumeration->fields_or_args, var_t, entry )
if (type_enum_get_values(enumeration))
LIST_FOR_EACH_ENTRY( cur, type_enum_get_values(enumeration), var_t, entry )
add_var_desc(msft_typeinfo, idx++, cur);
}