[PATCH 04/15] widl: move type_t's orig member to new alias_details struct and refactor to use decl_spec_t and added asserts in relevant places to ensure we're not dealing a typedef when accessing type's details member

Richard Pospesel richard at torproject.org
Fri Jul 5 16:51:33 CDT 2019


Signed-off-by: Richard Pospesel <richard at torproject.org>
---
 tools/widl/client.c     |  4 +--
 tools/widl/header.c     | 52 +++++++++++++++--------------
 tools/widl/header.h     |  2 +-
 tools/widl/parser.y     | 44 ++++++++++++++++--------
 tools/widl/proxy.c      | 28 ++++++++--------
 tools/widl/server.c     |  6 ++--
 tools/widl/typegen.c    | 74 +++++++++++++++++++++--------------------
 tools/widl/typetree.c   | 12 ++++---
 tools/widl/typetree.h   | 53 +++++++++++++++++++++++++++--
 tools/widl/widl.c       |  1 +
 tools/widl/widltypes.h  | 64 ++++++++++++-----------------------
 tools/widl/write_msft.c | 26 ++++++++-------
 12 files changed, 208 insertions(+), 158 deletions(-)

diff --git a/tools/widl/client.c b/tools/widl/client.c
index b0a5d0cc8c..545a35c0c9 100644
--- a/tools/widl/client.c
+++ b/tools/widl/client.c
@@ -34,7 +34,7 @@
 #include "parser.h"
 #include "header.h"
 
-#include "widltypes.h"
+#include "typetree.h"
 #include "typegen.h"
 #include "expr.h"
 
@@ -53,7 +53,7 @@ static void print_client( const char *format, ... )
 static void write_client_func_decl( const type_t *iface, const var_t *func )
 {
     const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
-    const var_list_t *args = type_get_function_args(func->declspec.type);
+    const var_list_t *args = type_function_get_args(func->declspec.type);
     type_t *rettype = type_function_get_rettype(func->declspec.type);
 
     if (!callconv) callconv = "__cdecl";
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 8c07564751..d8f31a69f9 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -75,7 +75,7 @@ int is_ptrchain_attr(const var_t *var, enum attr_type t)
             if (is_attr(type->attrs, t))
                 return 1;
             else if (type_is_alias(type))
-                type = type_alias_get_aliasee(type);
+                type = type_alias_get_aliasee_type(type);
             else if (is_ptr(type))
                 type = type_pointer_get_ref_type(type);
             else return 0;
@@ -91,7 +91,7 @@ int is_aliaschain_attr(const type_t *type, enum attr_type attr)
         if (is_attr(t->attrs, attr))
             return 1;
         else if (type_is_alias(t))
-            t = type_alias_get_aliasee(t);
+            t = type_alias_get_aliasee_type(t);
         else return 0;
     }
 }
@@ -602,7 +602,7 @@ unsigned int get_context_handle_offset( const type_t *type )
 
     while (!is_attr( type->attrs, ATTR_CONTEXTHANDLE ))
     {
-        if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+        if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
         else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
         else error( "internal error: %s is not a context handle\n", type->name );
     }
@@ -622,7 +622,7 @@ unsigned int get_generic_handle_offset( const type_t *type )
 
     while (!is_attr( type->attrs, ATTR_HANDLE ))
     {
-        if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+        if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
         else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
         else error( "internal error: %s is not a generic handle\n", type->name );
     }
@@ -701,7 +701,7 @@ void check_for_additional_prototype_types(type_t *type)
     }
 
     if (type_is_alias(type))
-      type = type_alias_get_aliasee(type);
+      type = type_alias_get_aliasee_type(type);
     else if (is_ptr(type))
       type = type_pointer_get_ref_type(type);
     else if (is_array(type))
@@ -789,7 +789,7 @@ static void write_generic_handle_routines(FILE *header)
 static void write_typedef(FILE *header, type_t *type)
 {
   fprintf(header, "typedef ");
-  write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
+  write_type_def_or_decl(header, type_alias_get_aliasee_type(type), FALSE, type->name);
   fprintf(header, ";\n");
 }
 
@@ -852,7 +852,7 @@ const type_t* get_explicit_generic_handle_type(const var_t* var)
     const type_t *t;
     for (t = var->declspec.type;
          is_ptr(t) || type_is_alias(t);
-         t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref_type(t))
+         t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
         if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
             is_attr(t->attrs, ATTR_HANDLE))
             return t;
@@ -863,7 +863,7 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
                                   unsigned char *explicit_fc, unsigned char *implicit_fc )
 {
     const var_t *var;
-    const var_list_t *args = type_get_function_args( func->declspec.type );
+    const var_list_t *args = type_function_get_args( func->declspec.type );
 
     *explicit_fc = *implicit_fc = 0;
     if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
@@ -907,10 +907,10 @@ int has_out_arg_or_return(const var_t *func)
     if (!is_void(type_function_get_rettype(func->declspec.type)))
         return 1;
 
-    if (!type_get_function_args(func->declspec.type))
+    if (!type_function_get_args(func->declspec.type))
         return 0;
 
-    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+    LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
         if (is_attr(var->attrs, ATTR_OUT))
             return 1;
 
@@ -1030,8 +1030,8 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t *
       const var_t *arg;
 
       fprintf(header, "#define %s_%s(This", name, get_name(func));
-      if (type_get_function_args(func->declspec.type))
-          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), const var_t, entry )
+      if (type_function_get_args(func->declspec.type))
+          LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
               fprintf(header, ",%s", arg->name);
       fprintf(header, ") ");
 
@@ -1042,8 +1042,8 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t *
       }
 
       fprintf(header, "(This)->lpVtbl->%s(This", get_vtbl_entry_name(iface, func));
-      if (type_get_function_args(func->declspec.type))
-          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), const var_t, entry )
+      if (type_function_get_args(func->declspec.type))
+          LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
               fprintf(header, ",%s", arg->name);
       fprintf(header, ")\n");
     }
@@ -1115,7 +1115,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
     const var_t *func = stmt->u.var;
     if (!is_callas(func->attrs)) {
       const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
-      const var_list_t *args = type_get_function_args(func->declspec.type);
+      const var_list_t *args = type_function_get_args(func->declspec.type);
       const var_t *arg;
 
       if (!callconv) callconv = "STDMETHODCALLTYPE";
@@ -1203,7 +1203,7 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
       fprintf(header, "static FORCEINLINE ");
       write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
       fprintf(header, " %s_%s(", name, get_name(func));
-      write_args(header, type_get_function_args(func->declspec.type), name, 1, FALSE);
+      write_args(header, type_function_get_args(func->declspec.type), name, 1, FALSE);
       fprintf(header, ") {\n");
       ++indentation;
       if (!is_aggregate_return(func)) {
@@ -1218,8 +1218,8 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
         indent(header, 0);
         fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_vtbl_entry_name(iface, func));
       }
-      if (type_get_function_args(func->declspec.type))
-          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), const var_t, entry )
+      if (type_function_get_args(func->declspec.type))
+          LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
               fprintf(header, ",%s", arg->name);
       fprintf(header, ");\n");
       --indentation;
@@ -1265,9 +1265,9 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
         fprintf(header, " *__ret");
       }
       --indentation;
-      if (type_get_function_args(func->declspec.type)) {
+      if (type_function_get_args(func->declspec.type)) {
         fprintf(header, ",\n");
-        write_args(header, type_get_function_args(func->declspec.type), name, 0, TRUE);
+        write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE);
       }
       fprintf(header, ");\n");
       fprintf(header, "\n");
@@ -1299,7 +1299,7 @@ static void write_method_proto(FILE *header, const type_t *iface)
       /* proxy prototype */
       write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
       fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
-      write_args(header, type_get_function_args(func->declspec.type), iface->name, 1, TRUE);
+      write_args(header, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
       fprintf(header, ");\n");
       /* stub prototype */
       fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func));
@@ -1334,7 +1334,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
         /* proxy prototype - use local prototype */
         write_type_decl_left(fp, type_function_get_rettype(m->declspec.type));
         fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m));
-        write_args(fp, type_get_function_args(m->declspec.type), iface->name, 1, TRUE);
+        write_args(fp, type_function_get_args(m->declspec.type), iface->name, 1, TRUE);
         fprintf(fp, ")");
         if (body) {
           type_t *rt = type_function_get_rettype(m->declspec.type);
@@ -1356,7 +1356,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
         /* stub prototype - use remotable prototype */
         write_type_decl_left(fp, type_function_get_rettype(func->declspec.type));
         fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m));
-        write_args(fp, type_get_function_args(func->declspec.type), iface->name, 1, TRUE);
+        write_args(fp, type_function_get_args(func->declspec.type), iface->name, 1, TRUE);
         fprintf(fp, ")");
         if (body)
           /* Remotable methods must all return HRESULTs.  */
@@ -1409,8 +1409,8 @@ static void write_function_proto(FILE *header, const type_t *iface, const var_t
   write_type_decl_left(header, type_function_get_rettype(fun->declspec.type));
   fprintf(header, " %s ", callconv);
   fprintf(header, "%s%s(\n", prefix, get_name(fun));
-  if (type_get_function_args(fun->declspec.type))
-    write_args(header, type_get_function_args(fun->declspec.type), iface->name, 0, TRUE);
+  if (type_function_get_args(fun->declspec.type))
+    write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE);
   else
     fprintf(header, "    void");
   fprintf(header, ");\n\n");
@@ -1648,6 +1648,7 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
         if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
         {
           type_t *iface = stmt->u.type;
+          assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
           if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
           {
             write_forward(header, iface);
@@ -1689,6 +1690,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
         {
           type_t *iface = stmt->u.type;
           type_t *async_iface = iface->details.iface->async_iface;
+          assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
           if (is_object(iface)) is_object_interface++;
           if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
           {
diff --git a/tools/widl/header.h b/tools/widl/header.h
index eb98125b25..94b90a391f 100644
--- a/tools/widl/header.h
+++ b/tools/widl/header.h
@@ -102,7 +102,7 @@ static inline int is_context_handle(const type_t *type)
     const type_t *t;
     for (t = type;
          is_ptr(t) || type_is_alias(t);
-         t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref_type(t))
+         t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
         if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
             return 1;
     return 0;
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index ff867655fa..82cf36d297 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1423,6 +1423,7 @@ void clear_all_offsets(void)
 
 static void type_function_add_head_arg(type_t *type, var_t *arg)
 {
+    assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
     if (!type->details.function->args)
     {
         type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
@@ -1482,6 +1483,7 @@ static type_t *append_chain_type(type_t *chain, type_t *type)
     for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
         ;
 
+    assert(!type_is_alias(chain_type));
     if (is_ptr(chain_type))
         chain_type->details.pointer.ref.type = type;
     else if (is_array(chain_type))
@@ -1550,7 +1552,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
     {
       ptr_attr = get_attrv(ptr->attrs, ATTR_POINTERTYPE);
       if (!ptr_attr && type_is_alias(ptr))
-        ptr = type_alias_get_aliasee(ptr);
+        ptr = type_alias_get_aliasee_type(ptr);
       else
         break;
     }
@@ -1561,7 +1563,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
           warning_loc_info(&v->loc_info,
                            "%s: pointer attribute applied to interface "
                            "pointer type has no effect\n", v->name);
-      if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
+      if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
       {
         /* FIXME: this is a horrible hack to cope with the issue that we
          * store an offset to the typeformat string in the type object, but
@@ -1634,6 +1636,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
         error_loc("%s: size_is attribute applied to illegal type\n", v->name);
     }
 
+    assert(!type_is_alias(*ptype));
     if (is_ptr(*ptype))
       ptype = &(*ptype)->details.pointer.ref.type;
     else if (is_array(*ptype))
@@ -1660,6 +1663,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
         error_loc("%s: length_is attribute applied to illegal type\n", v->name);
     }
 
+    assert(!type_is_alias(*ptype));
     if (is_ptr(*ptype))
       ptype = &(*ptype)->details.pointer.ref.type;
     else if (is_array(*ptype))
@@ -1902,7 +1906,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
 static int is_incomplete(const type_t *t)
 {
   return !t->defined &&
-    (type_get_type_detect_alias(t) == TYPE_STRUCT ||
+    (type_get_type_detect_alias(t) == TYPE_ENUM ||
+     type_get_type_detect_alias(t) == TYPE_STRUCT ||
      type_get_type_detect_alias(t) == TYPE_UNION ||
      type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
 }
@@ -1910,19 +1915,16 @@ static int is_incomplete(const type_t *t)
 void add_incomplete(type_t *t)
 {
   struct typenode *tn = xmalloc(sizeof *tn);
+  assert(is_incomplete(t));
   tn->type = t;
   list_add_tail(&incomplete_types, &tn->entry);
 }
 
 static void fix_type(type_t *t)
 {
-  if (type_is_alias(t) && is_incomplete(t)) {
-    type_t *ot = type_alias_get_aliasee(t);
-    fix_type(ot);
-    if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
-        type_get_type_detect_alias(ot) == TYPE_UNION ||
-        type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
-      t->details.structure = ot->details.structure;
+  if (type_is_alias(t) && is_incomplete(t)) 
+  {
+    type_t *ot = type_alias_get_aliasee_type(t);
     t->defined = ot->defined;
   }
 }
@@ -1946,7 +1948,7 @@ static void fix_incomplete_types(type_t *complete_type)
   {
     if (type_is_equal(complete_type, tn->type))
     {
-      tn->type->details.structure = complete_type->details.structure;
+      tn->type->details = complete_type->details;
       list_remove(&tn->entry);
       free(tn);
     }
@@ -2651,10 +2653,15 @@ static void check_field_common(const type_t *container_type,
             type = type_array_get_element_type(type);
             more_to_do = TRUE;
             break;
+        case TGT_ENUM:
+            type = type_get_real_type(type);
+            if(!type_is_complete(type))
+            {
+                error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
+            }
         case TGT_USER_TYPE:
         case TGT_IFACE_POINTER:
         case TGT_BASIC:
-        case TGT_ENUM:
         case TGT_RANGE:
             /* nothing to do */
             break;
@@ -2679,10 +2686,15 @@ static void check_remoting_fields(const var_t *var, type_t *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);
+            error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
     }
     else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
-        fields = type_union_get_cases(type);
+    {
+    	if (type_is_complete(type))
+            fields = type_union_get_cases(type);
+        else
+            error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
+    }
 
     if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
         if (field->declspec.type) check_field_common(type, type->name, field);
@@ -2694,6 +2706,7 @@ static void check_remoting_args(const var_t *func)
     const char *funcname = func->name;
     const var_t *arg;
 
+    assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
     if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
     {
         const type_t *type = arg->declspec.type;
@@ -2828,6 +2841,7 @@ static void check_async_uuid(type_t *iface)
     type_t *async_iface;
     type_t *inherit;
 
+    assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
     if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
 
     inherit = iface->details.iface->inherit;
@@ -2844,6 +2858,7 @@ static void check_async_uuid(type_t *iface)
         var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
         var_list_t *begin_args = NULL, *finish_args = NULL, *args;
 
+        assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
         args = func->declspec.type->details.function->args;
         if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
         {
@@ -2914,6 +2929,7 @@ static void check_all_user_types(const statement_list_t *stmts)
       const statement_t *stmt_func;
       STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) {
         const var_t *func = stmt_func->u.var;
+        assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
         if (func->declspec.type->details.function->args)
           LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
             check_for_additional_prototype_types(v->declspec.type);
diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
index 8f65e8aa7b..5b5a092c83 100644
--- a/tools/widl/proxy.c
+++ b/tools/widl/proxy.c
@@ -195,7 +195,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
   int has_ret = !is_void(retval->declspec.type);
   int has_full_pointer = is_full_pointer_function(func);
   const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
-  const var_list_t *args = type_get_function_args(func->declspec.type);
+  const var_list_t *args = type_function_get_args(func->declspec.type);
   if (!callconv) callconv = "STDMETHODCALLTYPE";
 
   indent = 0;
@@ -246,7 +246,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
     write_full_pointer_init(proxy, indent, func, FALSE);
 
   /* FIXME: trace */
-  clear_output_vars( type_get_function_args(func->declspec.type) );
+  clear_output_vars( type_function_get_args(func->declspec.type) );
 
   print_proxy( "RpcTryExcept\n" );
   print_proxy( "{\n" );
@@ -301,7 +301,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
   print_proxy( "{\n" );
   if (has_ret) {
     indent++;
-    proxy_free_variables( type_get_function_args(func->declspec.type), "" );
+    proxy_free_variables( type_function_get_args(func->declspec.type), "" );
     print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" );
     indent--;
   }
@@ -389,9 +389,9 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
   else fprintf(proxy, "__frame->_This->lpVtbl->%s", get_name(func));
   fprintf(proxy, "(__frame->_This");
 
-  if (type_get_function_args(func->declspec.type))
+  if (type_function_get_args(func->declspec.type))
   {
-      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), const var_t, entry )
+      LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
           fprintf(proxy, ", %s__frame->%s", is_array(arg->declspec.type) && !type_array_is_decl_as_ptr(arg->declspec.type) ? "*" :"" , arg->name);
   }
   fprintf(proxy, ");\n");
@@ -434,7 +434,7 @@ static void gen_stub_thunk( type_t *iface, const var_t *func, unsigned int proc_
 {
     int has_ret = !is_void( type_function_get_rettype( func->declspec.type ));
     const var_t *arg, *callas = is_callas( func->attrs );
-    const var_list_t *args = type_get_function_args( func->declspec.type );
+    const var_list_t *args = type_function_get_args( func->declspec.type );
 
     indent = 0;
     print_proxy( "void __RPC_API %s_%s_Thunk( PMIDL_STUB_MESSAGE pStubMsg )\n",
@@ -614,14 +614,14 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
     if (!is_local(func->attrs)) {
       const var_t *cas = is_callas(func->attrs);
       const char *cname = cas ? cas->name : NULL;
-      int idx = func->declspec.type->details.function->idx;
+      int idx = type_get_details(func->declspec.type)->function->idx;
       if (cname) {
           const statement_t *stmt2;
           STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) {
               const var_t *m = stmt2->u.var;
               if (!strcmp(m->name, cname))
               {
-                  idx = m->declspec.type->details.function->idx;
+                  idx = type_get_details(m->declspec.type)->function->idx;
                   break;
               }
           }
@@ -739,7 +739,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
   print_proxy( "{\n");
   indent++;
   print_proxy( "%s_%s\n",
-               iface->details.iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
+               type_get_details(iface)->iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
                need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
   indent--;
   print_proxy( "}\n");
@@ -840,8 +840,8 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
       if (need_proxy(iface))
       {
         write_proxy(iface, proc_offset);
-        if (iface->details.iface->async_iface)
-          write_proxy(iface->details.iface->async_iface, proc_offset);
+        if (type_get_details(iface)->iface->async_iface)
+          write_proxy(type_get_details(iface)->iface->async_iface, proc_offset);
       }
     }
   }
@@ -870,9 +870,9 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
             {
                 *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
                 (*ifaces)[(*count)++] = iface;
-                if (iface->details.iface->async_iface)
+                if (type_get_details(iface)->iface->async_iface)
                 {
-                    iface = iface->details.iface->async_iface;
+                    iface = type_get_details(iface)->iface->async_iface;
                     *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
                     (*ifaces)[(*count)++] = iface;
                 }
@@ -1012,7 +1012,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
   table_version = get_stub_mode() == MODE_Oif ? 2 : 1;
   for (i = 0; i < count; i++)
   {
-      if (interfaces[i]->details.iface->async_iface != interfaces[i]) continue;
+      if (type_get_details(interfaces[i])->iface->async_iface != interfaces[i]) continue;
       if (table_version != 6)
       {
           fprintf(proxy, "static const IID *_AsyncInterfaceTable[] =\n");
diff --git a/tools/widl/server.c b/tools/widl/server.c
index fb14dd87bc..6ce3db5e1c 100644
--- a/tools/widl/server.c
+++ b/tools/widl/server.c
@@ -121,7 +121,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
     if (has_full_pointer)
         write_full_pointer_init(server, indent, func, TRUE);
 
-    if (type_get_function_args(func->declspec.type))
+    if (type_function_get_args(func->declspec.type))
     {
         print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
         indent++;
@@ -166,13 +166,13 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
         print_server("%s", is_void(ret_type) ? "" : "__frame->_RetVal = ");
     fprintf(server, "%s%s", prefix_server, get_name(func));
 
-    if (type_get_function_args(func->declspec.type))
+    if (type_function_get_args(func->declspec.type))
     {
         int first_arg = 1;
 
         fprintf(server, "(\n");
         indent++;
-        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+        LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
         {
             if (first_arg)
                 first_arg = 0;
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index f901f83d1e..ddf555cd9b 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -197,7 +197,7 @@ static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr)
         if (is_attr(t->attrs, attr))
             return get_attrp(t->attrs, attr);
         else if (type_is_alias(t))
-            t = type_alias_get_aliasee(t);
+            t = type_alias_get_aliasee_type(t);
         else return NULL;
     }
 }
@@ -267,7 +267,7 @@ unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int t
     if (pointer_type)
         return pointer_type;
 
-    for (t = type; type_is_alias(t); t = type_alias_get_aliasee(t))
+    for (t = type; type_is_alias(t); t = type_alias_get_aliasee_type(t))
     {
         pointer_type = get_attrv(t->attrs, ATTR_POINTERTYPE);
         if (pointer_type)
@@ -316,7 +316,7 @@ static type_t *get_user_type(const type_t *t, const char **pname)
         }
 
         if (type_is_alias(t))
-            t = type_alias_get_aliasee(t);
+            t = type_alias_get_aliasee_type(t);
         else
             return NULL;
     }
@@ -857,7 +857,7 @@ static const char *get_context_handle_type_name(const type_t *type)
     const type_t *t;
     for (t = type;
          is_ptr(t) || type_is_alias(t);
-         t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref_type(t))
+         t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
         if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
             return t->name;
     assert(0);
@@ -912,10 +912,10 @@ void write_parameters_init(FILE *file, int indent, const var_t *func, const char
     if (!is_void(var->declspec.type))
         write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
 
-    if (!type_get_function_args(func->declspec.type))
+    if (!type_function_get_args(func->declspec.type))
         return;
 
-    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+    LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
         write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
 
     fprintf(file, "\n");
@@ -1011,7 +1011,7 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
         break;
     case TGT_ARRAY:
         *flags |= MustFree;
-        if (type_array_is_decl_as_ptr(var->declspec.type) && var->declspec.type->details.array.ptr_tfsoff &&
+        if (type_array_is_decl_as_ptr(var->declspec.type) && type_get_details(var->declspec.type)->array.ptr_tfsoff &&
             get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
         {
             *typestring_offset = var->declspec.type->typestring_offset;
@@ -1128,7 +1128,7 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
 static unsigned char get_func_oi2_flags( const var_t *func )
 {
     const var_t *var;
-    var_list_t *args = type_get_function_args( func->declspec.type );
+    var_list_t *args = type_function_get_args( func->declspec.type );
     var_t *retval = type_function_get_retval( func->declspec.type );
     unsigned char oi2_flags = 0x40;  /* HasExtensions */
     unsigned short flags;
@@ -1230,8 +1230,10 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
 
         if (!is_interpreted && is_array(var->declspec.type) &&
             type_array_is_decl_as_ptr(var->declspec.type) &&
-            var->declspec.type->details.array.ptr_tfsoff)
+            type_get_details(var->declspec.type)->array.ptr_tfsoff)
+        {
             offset = var->declspec.type->typestring_offset;
+        }
 
         if (is_return)
             print_file(file, indent, "0x52,    /* FC_RETURN_PARAM */\n");
@@ -1254,7 +1256,7 @@ int is_interpreted_func( const type_t *iface, const var_t *func )
 {
     const char *str;
     const var_t *var;
-    const var_list_t *args = type_get_function_args( func->declspec.type );
+    const var_list_t *args = type_function_get_args( func->declspec.type );
     const type_t *ret_type = type_function_get_rettype( func->declspec.type );
 
     if (type_get_type( ret_type ) == TYPE_BASIC)
@@ -1305,7 +1307,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
                                     unsigned short num_proc )
 {
     var_t *var;
-    var_list_t *args = type_get_function_args( func->declspec.type );
+    var_list_t *args = type_function_get_args( func->declspec.type );
     unsigned char explicit_fc, implicit_fc;
     unsigned char handle_flags;
     const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
@@ -1394,7 +1396,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
 
         if (is_attr( func->attrs, ATTR_NOTIFY )) ext_flags |= 0x08;  /* HasNotify */
         if (is_attr( func->attrs, ATTR_NOTIFYFLAG )) ext_flags |= 0x10;  /* HasNotify2 */
-        if (iface == iface->details.iface->async_iface) oi2_flags |= 0x20;
+        if (iface == type_get_const_details(iface)->iface->async_iface) oi2_flags |= 0x20;
 
         size = get_function_buffer_size( func, PASS_IN );
         print_file( file, indent, "NdrFcShort(0x%x),\t/* client buffer = %u */\n", size, size );
@@ -1445,10 +1447,10 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
     if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc );
 
     /* emit argument data */
-    if (type_get_function_args(func->declspec.type))
+    if (type_function_get_args(func->declspec.type))
     {
         const var_t *var;
-        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+        LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
         {
             print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
             if (is_new_style)
@@ -1488,13 +1490,13 @@ static void for_each_iface(const statement_list_t *stmts,
 
     if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
     {
-        if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE)
+        if (stmt->type != STMT_TYPE || type_get_type_detect_alias(stmt->u.type) != TYPE_INTERFACE)
             continue;
         iface = stmt->u.type;
         if (!pred(iface)) continue;
         proc(iface, file, indent, offset);
-        if (iface->details.iface->async_iface)
-            proc(iface->details.iface->async_iface, file, indent, offset);
+        if (type_get_const_details(iface)->iface->async_iface)
+            proc(type_get_const_details(iface)->iface->async_iface, file, indent, offset);
     }
 }
 
@@ -1669,7 +1671,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
 
         if (type_get_type(cont_type) == TYPE_FUNCTION)
         {
-            var_list_t *args = type_get_function_args( cont_type );
+            var_list_t *args = type_function_get_args( cont_type );
 
             if (is_object( iface )) offset += pointer_size;
             if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
@@ -2079,9 +2081,9 @@ int is_full_pointer_function(const var_t *func)
     const var_t *var;
     if (type_has_full_pointer(type_function_get_rettype(func->declspec.type), func->attrs, TRUE))
         return TRUE;
-    if (!type_get_function_args(func->declspec.type))
+    if (!type_function_get_args(func->declspec.type))
         return FALSE;
-    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+    LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
         if (type_has_full_pointer( var->declspec.type, var->attrs, TRUE ))
             return TRUE;
     return FALSE;
@@ -3621,7 +3623,7 @@ static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
                 if (ptr_type != FC_RP) update_tfsoff( type, off, file );
                 *typeformat_offset += 4;
             }
-            type->details.array.ptr_tfsoff = off;
+            type_get_details(type)->array.ptr_tfsoff = off;
         }
         return off;
     }
@@ -3711,8 +3713,8 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
                 var->typestring_offset = write_type_tfs( file, var->attrs, var->declspec.type, func->name,
                                                          TYPE_CONTEXT_RETVAL, offset);
 
-            if (type_get_function_args(func->declspec.type))
-                LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), var_t, entry )
+            if (type_function_get_args(func->declspec.type))
+                LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), var_t, entry )
                     var->typestring_offset = write_type_tfs( file, var->attrs, var->declspec.type, var->name,
                                                              TYPE_CONTEXT_TOPLEVELPARAM, offset );
             break;
@@ -3911,9 +3913,9 @@ static unsigned int get_function_buffer_size( const var_t *func, enum pass pass
     const var_t *var;
     unsigned int total_size = 0, alignment;
 
-    if (type_get_function_args(func->declspec.type))
+    if (type_function_get_args(func->declspec.type))
     {
-        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+        LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
         {
             total_size += get_required_buffer_size(var, &alignment, pass);
             total_size += alignment;
@@ -4350,10 +4352,10 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
                 ((tc == FC_SMVARRAY || tc == FC_LGVARRAY) && in_attr) ||
                 (tc == FC_CARRAY && !in_attr))
             {
-                if (type_array_is_decl_as_ptr(type) && type->details.array.ptr_tfsoff)
+                if (type_array_is_decl_as_ptr(type) && type_get_const_details(type)->array.ptr_tfsoff)
                 {
                     print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var,
-                                         type->details.array.ptr_tfsoff);
+                                         type_get_const_details(type)->array.ptr_tfsoff);
                     break;
                 }
                 print_phase_function(file, indent, array_type, local_var_prefix, phase, var, start_offset);
@@ -4561,9 +4563,9 @@ void write_remoting_arguments(FILE *file, int indent, const var_t *func, const c
     else
     {
         const var_t *var;
-        if (!type_get_function_args(func->declspec.type))
+        if (!type_function_get_args(func->declspec.type))
             return;
-        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+        LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
             write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var );
     }
 }
@@ -4619,10 +4621,10 @@ void declare_stub_args( FILE *file, int indent, const var_t *func )
         }
     }
 
-    if (!type_get_function_args(func->declspec.type))
+    if (!type_function_get_args(func->declspec.type))
         return;
 
-    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+    LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
     {
         in_attr = is_attr(var->attrs, ATTR_IN);
         out_attr = is_attr(var->attrs, ATTR_OUT);
@@ -4673,10 +4675,10 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
     const var_t *var;
     type_t *ref;
 
-    if (!type_get_function_args(func->declspec.type))
+    if (!type_function_get_args(func->declspec.type))
         return;
 
-    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
+    LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), const var_t, entry )
     {
         in_attr = is_attr(var->attrs, ATTR_IN);
         out_attr = is_attr(var->attrs, ATTR_OUT);
@@ -4783,7 +4785,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
                               const char *var_decl, int add_retval )
 {
     var_t *retval = type_function_get_retval( func );
-    const var_list_t *args = type_get_function_args( func );
+    const var_list_t *args = type_function_get_args( func );
     const var_t *arg;
     int needs_packing;
     unsigned int align = 0;
@@ -4833,7 +4835,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
 
 void write_pointer_checks( FILE *file, int indent, const var_t *func )
 {
-    const var_list_t *args = type_get_function_args( func->declspec.type );
+    const var_list_t *args = type_function_get_args( func->declspec.type );
     const var_t *var;
 
     if (!args) return;
@@ -4965,7 +4967,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
 {
     type_t *rettype = type_function_get_rettype( func->declspec.type );
     int has_ret = !is_void( rettype );
-    const var_list_t *args = type_get_function_args( func->declspec.type );
+    const var_list_t *args = type_function_get_args( func->declspec.type );
     const var_t *arg;
     int len, needs_params = 0;
 
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 0a8ae0f3b2..4b37b0d524 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -49,7 +49,6 @@ type_t *make_type(enum type_type type)
     t->type_type = type;
     t->attrs = NULL;
     t->c_name = NULL;
-    t->orig = NULL;
     memset(&t->details, 0, sizeof(t->details));
     t->typestring_offset = 0;
     t->ptrdesc = 0;
@@ -189,14 +188,12 @@ type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t
 
 type_t *type_new_alias(type_t *t, const char *name)
 {
-    type_t *a = duptype(t, 0);
+    type_t *a = make_type(t->type_type);
 
     a->name = xstrdup(name);
     a->attrs = NULL;
-    a->orig = t;
+    a->details.alias.aliasee.type = t;
     a->is_alias = TRUE;
-    /* for pointer types */
-    a->details = t->details;
     init_loc_info(&a->loc_info);
 
     return a;
@@ -438,6 +435,7 @@ static int compute_method_indexes(type_t *iface)
 
 void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
 {
+    assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
     iface->details.iface->disp_props = NULL;
     iface->details.iface->disp_methods = NULL;
@@ -451,6 +449,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
 
 void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
 {
+    assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
     iface->details.iface = xmalloc(sizeof(*iface->details.iface));
     iface->details.iface->disp_props = props;
     iface->details.iface->disp_methods = methods;
@@ -465,6 +464,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
 
 void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
 {
+    assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
     dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
     dispiface->details.iface->disp_props = NULL;
     dispiface->details.iface->disp_methods = NULL;
@@ -479,6 +479,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
 
 void type_module_define(type_t *module, statement_list_t *stmts)
 {
+    assert(type_get_type_detect_alias(module) == TYPE_MODULE);
     if (module->details.module) error_loc("multiple definition error\n");
     module->details.module = xmalloc(sizeof(*module->details.module));
     module->details.module->stmts = stmts;
@@ -487,6 +488,7 @@ void type_module_define(type_t *module, statement_list_t *stmts)
 
 type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
 {
+    assert(type_get_type_detect_alias(coclass) == TYPE_COCLASS);
     coclass->details.coclass.ifaces = ifaces;
     coclass->defined = TRUE;
     return coclass;
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 22232fc0a7..1fd86bbc89 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -56,11 +56,35 @@ const char *type_get_name(const type_t *type, enum name_type name_type);
 /* FIXME: shouldn't need to export this */
 type_t *duptype(type_t *t, int dupname);
 
+#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
+  if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
+    if (stmt->type == STMT_DECLARATION && stmt->u.var->declspec.stgclass == STG_NONE && \
+        type_get_type_detect_alias(stmt->u.var->declspec.type) == TYPE_FUNCTION)
+
+static inline enum type_type type_get_type_detect_alias(const type_t *type)
+{
+    if (type->is_alias)
+        return TYPE_ALIAS;
+    return type->type_type;
+}
+
+static inline int statements_has_func(const statement_list_t *stmts)
+{
+  const statement_t *stmt;
+  int has_func = 0;
+  STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
+  {
+    has_func = 1;
+    break;
+  }
+  return has_func;
+}
+
 /* un-alias the type until finding the non-alias type */
 static inline type_t *type_get_real_type(const type_t *type)
 {
     if (type->is_alias)
-        return type_get_real_type(type->orig);
+        return type_get_real_type(type->details.alias.aliasee.type);
     else
         return (type_t *)type;
 }
@@ -281,10 +305,15 @@ static inline int type_is_alias(const type_t *type)
     return type->is_alias;
 }
 
-static inline type_t *type_alias_get_aliasee(const type_t *type)
+static inline const decl_spec_t *type_alias_get_aliasee(const type_t *type)
 {
     assert(type_is_alias(type));
-    return type->orig;
+    return &type->details.alias.aliasee;
+}
+
+static inline type_t *type_alias_get_aliasee_type(const type_t *type)
+{
+    return type_alias_get_aliasee(type)->type;
 }
 
 static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
@@ -327,4 +356,22 @@ static inline const expr_t *type_bitfield_get_bits(const type_t *type)
     return type->details.bitfield.bits;
 }
 
+/* gets pointer to details_t union with the assumption the caller wants to write to it
+ * so assert if we're actually dealing with an alias and writing to the details would
+ * overwrite the alias_details
+ */
+static inline details_t *type_get_details(type_t* type)
+{
+    assert(!type_is_alias(type));
+    return &type->details;
+}
+
+/* const overload of type_get_details */
+
+static inline const details_t *type_get_const_details(const type_t* type)
+{
+    assert(!type_is_alias(type));
+    return &type->details;
+}
+
 #endif /* WIDL_TYPE_TREE_H */
diff --git a/tools/widl/widl.c b/tools/widl/widl.c
index 0bcf67ba73..866c897ebb 100644
--- a/tools/widl/widl.c
+++ b/tools/widl/widl.c
@@ -494,6 +494,7 @@ static void write_id_data_stmts(const statement_list_t *stmts)
         uuid = get_attrp(type->attrs, ATTR_UUID);
         write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
                    type->name, uuid);
+        assert(type_get_type_detect_alias(type) == TYPE_INTERFACE);
         if (type->details.iface->async_iface)
         {
           uuid = get_attrp(type->details.iface->async_iface->attrs, ATTR_UUID);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index bd727f70b6..d637e0024c 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -394,6 +394,11 @@ struct bitfield_details
   const expr_t *bits;
 };
 
+struct alias_details
+{
+  struct _decl_spec_t aliasee;
+};
+
 #define HASHMAX 64
 
 struct namespace {
@@ -422,26 +427,28 @@ enum type_type
     TYPE_BITFIELD,
 };
 
+typedef union _details_t
+{
+  struct struct_details *structure;
+  struct enumeration_details *enumeration;
+  struct func_details *function;
+  struct iface_details *iface;
+  struct module_details *module;
+  struct array_details array;
+  struct coclass_details coclass;
+  struct basic_details basic;
+  struct pointer_details pointer;
+  struct bitfield_details bitfield;
+  struct alias_details alias;
+} details_t;
+
 struct _type_t {
   const char *name;
   struct namespace *namespace;
   enum type_type type_type;
   attr_list_t *attrs;
-  union
-  {
-    struct struct_details *structure;
-    struct enumeration_details *enumeration;
-    struct func_details *function;
-    struct iface_details *iface;
-    struct module_details *module;
-    struct array_details array;
-    struct coclass_details coclass;
-    struct basic_details basic;
-    struct pointer_details pointer;
-    struct bitfield_details bitfield;
-  } details;
+  details_t details;
   const char *c_name;
-  type_t *orig;                   /* dup'd types */
   unsigned int typestring_offset;
   unsigned int ptrdesc;           /* used for complex structs */
   int typelib_idx;
@@ -589,35 +596,6 @@ void init_loc_info(loc_info_t *);
 
 char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
 
-static inline var_list_t *type_get_function_args(const type_t *func_type)
-{
-  return func_type->details.function->args;
-}
-
-static inline enum type_type type_get_type_detect_alias(const type_t *type)
-{
-    if (type->is_alias)
-        return TYPE_ALIAS;
-    return type->type_type;
-}
-
-#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
-  if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
-    if (stmt->type == STMT_DECLARATION && stmt->u.var->declspec.stgclass == STG_NONE && \
-        type_get_type_detect_alias(stmt->u.var->declspec.type) == TYPE_FUNCTION)
-
-static inline int statements_has_func(const statement_list_t *stmts)
-{
-  const statement_t *stmt;
-  int has_func = 0;
-  STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
-  {
-    has_func = 1;
-    break;
-  }
-  return has_func;
-}
-
 static inline int is_global_namespace(const struct namespace *namespace)
 {
     return !namespace->name;
diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c
index 9a3edf7291..13d768ab2e 100644
--- a/tools/widl/write_msft.c
+++ b/tools/widl/write_msft.c
@@ -912,10 +912,10 @@ static int encode_type(
 
     case VT_SAFEARRAY:
 	{
-	type_t *element_type = type_alias_get_aliasee(type_array_get_element_type(type));
+	type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(type));
 	int next_vt = get_type_vt(element_type);
 
-	encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element_type(type)),
+	encode_type(typelib, next_vt, type_alias_get_aliasee_type(type_array_get_element_type(type)),
         &target_type, &child_size);
 
 	for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
@@ -968,7 +968,7 @@ static int encode_type(
         {
             /* typedef'd types without public attribute aren't included in the typelib */
             while (type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
-                type = type_alias_get_aliasee(type);
+                type = type_alias_get_aliasee_type(type);
 
             chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
                  type->name, type_get_type(type));
@@ -1114,7 +1114,7 @@ static int encode_var(
 	    if (target_type & 0x80000000) {
 		mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
 	    } else if (get_type_vt(ref) == VT_SAFEARRAY) {
-		type_t *element_type = type_alias_get_aliasee(type_array_get_element_type(ref));
+		type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(ref));
 		mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
 	    } else {
 		typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
@@ -1301,8 +1301,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
         return S_FALSE;
     }
 
-    if (type_get_function_args(func->declspec.type))
-      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), var_t, entry )
+    if (type_function_get_args(func->declspec.type))
+      LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
       {
         num_params++;
         if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
@@ -1471,10 +1471,10 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
         warning("unknown number of optional attrs\n");
     }
 
-    if (type_get_function_args(func->declspec.type))
+    if (type_function_get_args(func->declspec.type))
     {
       i = 0;
-      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), var_t, entry )
+      LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
       {
         int paramflags = 0;
         int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
@@ -1572,10 +1572,10 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
     if(typeinfo->typekind == TKIND_MODULE)
         namedata[9] |= 0x20;
 
-    if (type_get_function_args(func->declspec.type))
+    if (type_function_get_args(func->declspec.type))
     {
         i = 0;
-        LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), var_t, entry )
+        LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
         {
             /* don't give the last arg of a [propput*] func a name */
             if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */))
@@ -1977,6 +1977,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
     var_t *var;
     msft_typeinfo_t *msft_typeinfo;
 
+    assert(type_get_type_detect_alias(dispinterface) == TYPE_INTERFACE);
     if (-1 < dispinterface->typelib_idx)
         return;
 
@@ -2181,7 +2182,7 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
     if (-1 < tdef->typelib_idx)
         return;
 
-    type = type_alias_get_aliasee(tdef);
+    type = type_alias_get_aliasee_type(tdef);
 
     if (!type->name || strcmp(tdef->name, type->name) != 0)
     {
@@ -2297,6 +2298,7 @@ static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
     const statement_t *stmt;
     msft_typeinfo_t *msft_typeinfo;
 
+    assert(type_get_type_detect_alias(module) == TYPE_MODULE);
     if (-1 < module->typelib_idx)
         return;
 
@@ -2364,7 +2366,7 @@ static void add_entry(msft_typelib_t *typelib, const statement_t *stmt)
             if (is_attr(type_entry->type->attrs, ATTR_PUBLIC))
                 add_typedef_typeinfo(typelib, type_entry->type);
             else
-                add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type));
+                add_type_typeinfo(typelib, type_alias_get_aliasee_type(type_entry->type));
         }
         break;
     }
-- 
2.17.1




More information about the wine-devel mailing list