widl [2/6]: Represent typedefs with easier to use structures

Dan Hipschman dsh at linux.ucla.edu
Tue Aug 29 16:26:03 CDT 2006


This is the same as before.  I hope I addressed Rob's concerns in my replies,
and I hope I'm not sending this too soon for him or anybody else make more
comments.  If so, just comment anyway.  If using the kind field outside the
typelib code is really a problem, I think it would be easier to address that
later because it would require touching more code than just what this patch
changes, and that way I can move on to other work in the mean time.

ChangeLog:
* 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 3a4cea9..5de43c0 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -203,13 +203,14 @@ void write_type(FILE *h, type_t *t, cons
 {
   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, cons
         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 ch
 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 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 6358d98..ee670ef 100644
--- a/tools/widl/header.h
+++ b/tools/widl/header.h
@@ -38,7 +38,7 @@ extern void write_interface(type_t *ifac
 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 d70cc04..352837e 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 @@ #define tsUNION  3
 %type <type> dispinterface dispinterfacehdr dispinterfacedef
 %type <type> module modulehdr moduledef
 %type <type> base_type int_std
-%type <type> enumdef structdef typedef uniondef
+%type <type> enumdef structdef uniondef
 %type <ifref> gbl_statements coclass_ints coclass_int
 %type <tref> type
 %type <var> m_args no_args args arg
@@ -811,7 +812,7 @@ structdef: tSTRUCT t_ident '{' fields '}
                                                 }
 	;
 
-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,
 	| 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 t
   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 *r
   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( t
   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, v
       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, v
           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 5218070..3717f8a 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 9fb5bdd..688f611 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 eeaa627..e75db75 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 2307493..6530483 100644
--- a/tools/widl/write_msft.c
+++ b/tools/widl/write_msft.c
@@ -944,6 +944,11 @@ #endif
     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_typel
     }
 }
 
-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);
 }
 



More information about the wine-patches mailing list