From c117a20cdb5ffbe04fd334bd7139fdb9dd60978a Mon Sep 17 00:00:00 2001 From: Dan Hipschman Date: Tue, 29 Aug 2006 14:26:03 -0700 Subject: [PATCH] widl: Use type_t for typedefs, not var_t. Simplify representation. --- tools/widl/header.c | 45 ++++++--------------- tools/widl/header.h | 2 +- tools/widl/parser.y | 88 +++++++++++++++++++++++++++-------------- tools/widl/typelib.c | 16 ++++---- tools/widl/typelib.h | 2 +- tools/widl/widltypes.h | 2 +- tools/widl/write_msft.c | 19 ++++----- 7 files changed, 90 insertions(+), 84 deletions(-) diff --git a/tools/widl/header.c b/tools/widl/header.c index 3a4cea931d1..5de43c0aadb 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -203,13 +203,14 @@ void write_type(FILE *h, type_t *t, const var_t *v, const char *n) { int c; + if (t->is_const) fprintf(h, "const "); + if (n) fprintf(h, "%s", n); + else if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name); else { - if (t->is_const) fprintf(h, "const "); - if (t->type) { - if (t->sign > 0) fprintf(h, "signed "); - else if (t->sign < 0) fprintf(h, "unsigned "); - switch (t->type) { + if (t->sign > 0) fprintf(h, "signed "); + else if (t->sign < 0) fprintf(h, "unsigned "); + switch (t->type) { case RPC_FC_ENUM16: case RPC_FC_ENUM32: if (t->defined && !t->written && !t->ignore) { @@ -262,13 +263,6 @@ void write_type(FILE *h, type_t *t, const var_t *v, const char *n) break; default: fprintf(h, "%s", t->name); - } - } - else { - if (t->ref) { - write_type(h, t->ref, NULL, t->name); - } - else fprintf(h, "void"); } } if (v) { @@ -299,9 +293,9 @@ static int user_type_registered(const char *name) static void check_for_user_types(const var_t *v) { while (v) { - type_t *type = v->type; - const char *name = v->tname; - for (type = v->type; type; type = type->ref) { + type_t *type; + for (type = v->type; type; type = type->kind == TKIND_ALIAS ? type->orig : type->ref) { + const char *name = type->name; if (type->user_types_registered) continue; type->user_types_registered = 1; if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { @@ -322,10 +316,6 @@ static void check_for_user_types(const var_t *v) while (NEXT_LINK(fields)) fields = NEXT_LINK(fields); check_for_user_types(fields); } - /* the wire_marshal attribute is always at least one reference away - * from the name of the type, so update it after the rest of the - * processing above */ - if (type->name) name = type->name; } v = PREV_LINK(v); } @@ -344,22 +334,11 @@ void write_user_types(void) } } -void write_typedef(type_t *type, const var_t *names) +void write_typedef(type_t *type) { - const char *tname = names->tname; - const var_t *lname; - while (NEXT_LINK(names)) names = NEXT_LINK(names); - lname = names; fprintf(header, "typedef "); - write_type(header, type, NULL, tname); - fprintf(header, " "); - while (names) { - write_pident(header, names); - if (PREV_LINK(names)) - fprintf(header, ", "); - names = PREV_LINK(names); - } - fprintf(header, ";\n"); + write_type(header, type->orig, NULL, NULL); + fprintf(header, " %s;\n", type->name); } void write_expr(FILE *h, const expr_t *e, int brackets) diff --git a/tools/widl/header.h b/tools/widl/header.h index 6358d98f7ec..ee670efc50e 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -38,7 +38,7 @@ extern void write_interface(type_t *iface); extern void write_dispinterface(type_t *iface); extern void write_coclass(type_t *cocl); extern void write_coclass_forward(type_t *cocl); -extern void write_typedef(type_t *type, const var_t *names); +extern void write_typedef(type_t *type); extern void write_expr(FILE *h, const expr_t *e, int brackets); extern void write_constdef(const var_t *v); extern void write_externdef(const var_t *v); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index d70cc0461a6..352837e028b 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -88,7 +88,7 @@ static type_t *make_builtin(char *name); static type_t *make_int(int sign); static type_t *reg_type(type_t *type, const char *name, int t); -static type_t *reg_types(type_t *type, var_t *names, int t); +static type_t *reg_typedefs(type_t *type, var_t *names, attr_t *attrs); static type_t *find_type(const char *name, int t); static type_t *find_type2(char *name, int t); static type_t *get_type(unsigned char type, char *name, int t); @@ -105,6 +105,7 @@ static void write_iid(type_t *iface); static int compute_method_indexes(type_t *iface); static char *gen_name(void); +static void process_typedefs(var_t *names); #define tsENUM 1 #define tsSTRUCT 2 @@ -214,7 +215,7 @@ static char *gen_name(void); %type dispinterface dispinterfacehdr dispinterfacedef %type module modulehdr moduledef %type base_type int_std -%type enumdef structdef typedef uniondef +%type enumdef structdef uniondef %type gbl_statements coclass_ints coclass_int %type type %type m_args no_args args arg @@ -811,7 +812,7 @@ structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, ts } ; -type: tVOID { $$ = make_tref(NULL, make_type(0, NULL)); } +type: tVOID { $$ = make_tref(NULL, duptype(find_type("void", 0), 1)); } | aKNOWNTYPE { $$ = make_tref($1, find_type($1, 0)); } | base_type { $$ = make_tref(NULL, $1); } | tCONST type { $$ = uniq_tref($2); $$->ref->is_const = TRUE; } @@ -824,26 +825,8 @@ type: tVOID { $$ = make_tref(NULL, make_type(0, NULL)); } | tSAFEARRAY '(' type ')' { $$ = make_tref(NULL, make_safearray()); } ; -typedef: tTYPEDEF m_attributes type pident_list { typeref_t *tref = uniq_tref($3); - type_t *t; - $4->tname = tref->name; - tref->name = NULL; - $$ = type_ref(tref); - t = $$->ref; - if ((t->kind == TKIND_ENUM || t->kind == TKIND_RECORD - || t->kind == TKIND_UNION) && ! t->name && ! parse_only) - { - attr_t *a = make_attr(ATTR_PUBLIC); - LINK(a, $2); - $2 = a; - t->name = gen_name(); - } - $$->attrs = $2; - if (!parse_only && do_header) - write_typedef($$, $4); - if (in_typelib && $$->attrs) - add_typedef($$, $4); - reg_types($$, $4, 0); +typedef: tTYPEDEF m_attributes type pident_list { reg_typedefs(type_ref($3), $4, $2); + process_typedefs($4); } ; @@ -902,6 +885,7 @@ static type_t *make_int(int sign) void init_types(void) { + decl_builtin("void", 0); decl_builtin("byte", RPC_FC_BYTE); decl_builtin("wchar_t", RPC_FC_WCHAR); decl_builtin("int", RPC_FC_LONG); /* win32 */ @@ -1147,6 +1131,7 @@ static type_t *make_type(unsigned char type, type_t *ref) t->type = type; t->ref = ref; t->attrs = NULL; + t->orig = NULL; t->funcs = NULL; t->fields = NULL; t->ifaces = NULL; @@ -1175,8 +1160,15 @@ static typeref_t *uniq_tref(typeref_t *ref) typeref_t *t = ref; type_t *tp; if (t->uniq) return t; - tp = make_type(0, t->ref); - tp->name = t->name; + + if (t->name) + { + tp = duptype(t->ref, 0); + tp->name = t->name; + } + else + tp = duptype(t->ref, 1); + t->name = NULL; t->ref = tp; t->uniq = 1; @@ -1311,11 +1303,27 @@ static unsigned char get_pointer_type( type_t *type ) return RPC_FC_FP; } -static type_t *reg_types(type_t *type, var_t *names, int t) +static type_t *reg_typedefs(type_t *type, var_t *names, attr_t *attrs) { type_t *ptr = type; int ptrc = 0; + /* We must generate names for tagless enum, struct or union. + Typedef-ing a tagless enum, struct or union means we want the typedef + to be included in a library whether it has other attributes or not, + hence the public attribute. */ + if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD + || type->kind == TKIND_UNION) && ! type->name && ! parse_only) + { + if (! is_attr(attrs, ATTR_PUBLIC)) + { + attr_t *new_attrs = make_attr(ATTR_PUBLIC); + LINK(new_attrs, attrs); + attrs = new_attrs; + } + type->name = gen_name(); + } + while (names) { var_t *next = NEXT_LINK(names); if (names->name) { @@ -1323,8 +1331,7 @@ static type_t *reg_types(type_t *type, var_t *names, int t) int cptr = names->ptr_level; if (cptr > ptrc) { while (cptr > ptrc) { - int t = get_pointer_type( cur ); - cur = ptr = make_type(t, cur); + cur = ptr = make_type(RPC_FC_RP, cur); ptrc++; } } else { @@ -1333,9 +1340,12 @@ static type_t *reg_types(type_t *type, var_t *names, int t) cptr++; } } - reg_type(cur, names->name, t); + cur = alias(cur, names->name); + cur->attrs = attrs; + if (cur->ref) + cur->type = get_pointer_type(cur); + reg_type(cur, cur->name, 0); } - free(names); names = next; } return type; @@ -1650,3 +1660,21 @@ static char *gen_name(void) sprintf(name, format, file_id, n++); return name; } + +static void process_typedefs(var_t *names) +{ + END_OF_LIST(names); + while (names) + { + var_t *next = PREV_LINK(names); + type_t *type = find_type(names->name, 0); + + if (! parse_only && do_header) + write_typedef(type); + if (in_typelib && type->attrs) + add_typedef(type); + + free(names); + names = next; + } +} diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index 52180705858..3717f8ad404 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -137,6 +137,9 @@ unsigned short get_type_vt(type_t *t) if (vt) return vt; } + if (t->kind == TKIND_ALIAS && t->attrs) + return VT_USERDEFINED; + switch (t->type) { case RPC_FC_BYTE: case RPC_FC_USMALL: @@ -189,9 +192,7 @@ unsigned short get_type_vt(type_t *t) case RPC_FC_BOGUS_STRUCT: return VT_USERDEFINED; case 0: - if(t->attrs) - return VT_USERDEFINED; - return 0; + return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED; default: error("get_type_vt: unknown type: 0x%02x\n", t->type); } @@ -300,18 +301,15 @@ void add_enum(type_t *enumeration) typelib->entry = entry; } -void add_typedef(type_t *tdef, var_t *name) +void add_typedef(type_t *tdef) { typelib_entry_t *entry; if (!typelib) return; - chat("add typedef: %s\n", name->name); + chat("add typedef: %s\n", tdef->name); entry = xmalloc(sizeof(*entry)); entry->kind = TKIND_ALIAS; - entry->u.tdef = xmalloc(sizeof(*entry->u.tdef)); - memcpy(entry->u.tdef, name, sizeof(*name)); - entry->u.tdef->type = tdef; - entry->u.tdef->name = xstrdup(name->name); + entry->u.tdef = tdef; LINK(entry, typelib->entry); typelib->entry = entry; } diff --git a/tools/widl/typelib.h b/tools/widl/typelib.h index 9fb5bdd9345..688f61155a0 100644 --- a/tools/widl/typelib.h +++ b/tools/widl/typelib.h @@ -29,7 +29,7 @@ extern void add_coclass(type_t *cls); extern void add_module(type_t *module); extern void add_struct(type_t *structure); extern void add_enum(type_t *enumeration); -extern void add_typedef(type_t *tdef, var_t *name); +extern void add_typedef(type_t *tdef); extern void add_importlib(const char *name); /* Copied from wtypes.h. Not included directly because that would create a diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index eeaa627200f..e75db75a826 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -260,7 +260,7 @@ struct _typelib_entry_t { type_t *module; type_t *structure; type_t *enumeration; - var_t *tdef; + type_t *tdef; } u; DECL_LINK(typelib_entry_t); }; diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 23074936c8b..6530483f06b 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -944,6 +944,11 @@ static int encode_type( case VT_USERDEFINED: { int typeinfo_offset; + + /* typedef'd types without attributes aren't included in the typelib */ + while (type->typelib_idx < 0 && type->kind == TKIND_ALIAS && ! type->attrs) + type = type->orig; + chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type, type->name, type->type, type->typelib_idx); @@ -2048,23 +2053,19 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration) } } -static void add_typedef_typeinfo(msft_typelib_t *typelib, var_t *tdef) +static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef) { msft_typeinfo_t *msft_typeinfo; int alignment; - const attr_t *attrs; - if (-1 < tdef->type->typelib_idx) + if (-1 < tdef->typelib_idx) return; - tdef->type->typelib_idx = typelib->typelib_header.nrtypeinfos; - msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->type->attrs, + tdef->typelib_idx = typelib->typelib_header.nrtypeinfos; + msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->attrs, typelib->typelib_header.nrtypeinfos); - attrs = tdef->type->attrs; - tdef->type->attrs = NULL; - encode_var(typelib, tdef, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, + encode_type(typelib, get_type_vt(tdef->orig), tdef->orig, &msft_typeinfo->typeinfo->datatype1, &msft_typeinfo->typeinfo->size, &alignment, &msft_typeinfo->typeinfo->datatype2); - tdef->type->attrs = attrs; msft_typeinfo->typeinfo->typekind |= (alignment << 11 | alignment << 6); }