[PATCH 01/15] widl: change struct _var_t's type member to a struct _decl_spec_t

Zebediah Figura z.figura12 at gmail.com
Wed Aug 7 21:50:52 CDT 2019


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>

On 7/5/19 4:49 PM, Richard Pospesel wrote:
> Signed-off-by: Richard Pospesel <richard at torproject.org>
> ---
>   tools/widl/client.c     |  32 ++--
>   tools/widl/expr.c       |   8 +-
>   tools/widl/header.c     | 116 +++++++-------
>   tools/widl/parser.y     | 113 +++++++-------
>   tools/widl/proxy.c      |  58 +++----
>   tools/widl/server.c     |  16 +-
>   tools/widl/typegen.c    | 334 ++++++++++++++++++++--------------------
>   tools/widl/typetree.c   |   8 +-
>   tools/widl/typetree.h   |   4 +-
>   tools/widl/widltypes.h  |  25 ++-
>   tools/widl/write_msft.c |  22 +--
>   11 files changed, 372 insertions(+), 364 deletions(-)
> 
> diff --git a/tools/widl/client.c b/tools/widl/client.c
> index fe88f5993c..b0a5d0cc8c 100644
> --- a/tools/widl/client.c
> +++ b/tools/widl/client.c
> @@ -52,9 +52,9 @@ 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->type->attrs, ATTR_CALLCONV);
> -    const var_list_t *args = type_get_function_args(func->type);
> -    type_t *rettype = type_function_get_rettype(func->type);
> +    const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
> +    const var_list_t *args = type_get_function_args(func->declspec.type);
> +    type_t *rettype = type_function_get_rettype(func->declspec.type);
>   
>       if (!callconv) callconv = "__cdecl";
>       write_type_decl_left(client, rettype);
> @@ -74,9 +74,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
>   {
>       unsigned char explicit_fc, implicit_fc;
>       int has_full_pointer = is_full_pointer_function(func);
> -    var_t *retval = type_function_get_retval(func->type);
> +    var_t *retval = type_function_get_retval(func->declspec.type);
>       const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
> -    int has_ret = !is_void(retval->type);
> +    int has_ret = !is_void(retval->declspec.type);
>   
>       if (is_interpreted_func( iface, func ))
>       {
> @@ -97,7 +97,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
>           print_client("RPC_BINDING_HANDLE _Handle;\n");
>       }
>   
> -    if (has_ret && decl_indirect(retval->type))
> +    if (has_ret && decl_indirect(retval->declspec.type))
>       {
>           print_client("void *_p_%s;\n", retval->name);
>       }
> @@ -136,7 +136,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
>       if (has_ret)
>       {
>           print_client("%s", "");
> -        write_type_decl(client, retval->type, retval->name);
> +        write_type_decl(client, retval->declspec.type, retval->name);
>           fprintf(client, ";\n");
>       }
>       print_client("RPC_MESSAGE _RpcMessage;\n");
> @@ -147,7 +147,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
>           if (explicit_fc == FC_BIND_GENERIC)
>               print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name );
>       }
> -    if (has_ret && decl_indirect(retval->type))
> +    if (has_ret && decl_indirect(retval->declspec.type))
>       {
>           print_client("__frame->_p_%s = &%s;\n", retval->name, retval->name);
>       }
> @@ -194,7 +194,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
>           /* if the context_handle attribute appears in the chain of types
>            * without pointers being followed, then the context handle must
>            * be direct, otherwise it is a pointer */
> -        int is_ch_ptr = !is_aliaschain_attr(handle_var->type, ATTR_CONTEXTHANDLE);
> +        int is_ch_ptr = !is_aliaschain_attr(handle_var->declspec.type, ATTR_CONTEXTHANDLE);
>           print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", handle_var->name);
>           indent++;
>           print_client("__frame->_Handle = NDRCContextBinding(%s%s);\n",
> @@ -257,9 +257,9 @@ static void write_function_stub( const type_t *iface, const var_t *func,
>       /* unmarshal return value */
>       if (has_ret)
>       {
> -        if (decl_indirect(retval->type))
> +        if (decl_indirect(retval->declspec.type))
>               print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
> -        else if (is_ptr(retval->type) || is_array(retval->type))
> +        else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
>               print_client("%s = 0;\n", retval->name);
>           write_remoting_arguments(client, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
>       }
> @@ -365,8 +365,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
>           case STMT_DECLARATION:
>           {
>               const var_t *func = stmt->u.var;
> -            if (stmt->u.var->stgclass != STG_NONE
> -                || type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
> +            if (stmt->u.var->declspec.stgclass != STG_NONE
> +                || type_get_type_detect_alias(stmt->u.var->declspec.type) != TYPE_FUNCTION)
>                   continue;
>               write_function_stub( iface, func, method_count++, *proc_offset );
>               *proc_offset += get_size_procformatstring_func( iface, func );
> @@ -488,7 +488,7 @@ static void write_implicithandledecl(type_t *iface)
>   
>       if (implicit_handle)
>       {
> -        write_type_decl( client, implicit_handle->type, implicit_handle->name );
> +        write_type_decl( client, implicit_handle->declspec.type, implicit_handle->name );
>           fprintf(client, ";\n\n");
>       }
>   }
> @@ -532,8 +532,8 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
>   
>               LIST_FOR_EACH_ENTRY(stmt2, type_iface_get_stmts(iface), const statement_t, entry)
>               {
> -                if (stmt2->type == STMT_DECLARATION && stmt2->u.var->stgclass == STG_NONE &&
> -                    type_get_type_detect_alias(stmt2->u.var->type) == TYPE_FUNCTION)
> +                if (stmt2->type == STMT_DECLARATION && stmt2->u.var->declspec.stgclass == STG_NONE &&
> +                    type_get_type_detect_alias(stmt2->u.var->declspec.type) == TYPE_FUNCTION)
>                   {
>                       needs_stub = 1;
>                       break;
> diff --git a/tools/widl/expr.c b/tools/widl/expr.c
> index 2ed4aff6ad..7ec42db79f 100644
> --- a/tools/widl/expr.c
> +++ b/tools/widl/expr.c
> @@ -194,10 +194,10 @@ expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr)
>       expr_t *e;
>       type_t *tref;
>   
> -    if (var->stgclass != STG_NONE && var->stgclass != STG_REGISTER)
> +    if (var->declspec.stgclass != STG_NONE && var->declspec.stgclass != STG_REGISTER)
>           error_loc("invalid storage class for type expression\n");
>   
> -    tref = var->type;
> +    tref = var->declspec.type;
>   
>       e = xmalloc(sizeof(expr_t));
>       e->type = type;
> @@ -474,7 +474,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
>       if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
>           if (field->name && !strcmp(identifier, field->name))
>           {
> -            type = field->type;
> +            type = field->declspec.type;
>               *found_in_cont_type = 1;
>               break;
>           }
> @@ -482,7 +482,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
>       if (!type)
>       {
>           var_t *const_var = find_const(identifier, 0);
> -        if (const_var) type = const_var->type;
> +        if (const_var) type = const_var->declspec.type;
>       }
>   
>       return type;
> diff --git a/tools/widl/header.c b/tools/widl/header.c
> index f618e02f3d..3e8cbfae5e 100644
> --- a/tools/widl/header.c
> +++ b/tools/widl/header.c
> @@ -69,7 +69,7 @@ int is_ptrchain_attr(const var_t *var, enum attr_type t)
>           return 1;
>       else
>       {
> -        type_t *type = var->type;
> +        type_t *type = var->declspec.type;
>           for (;;)
>           {
>               if (is_attr(type->attrs, t))
> @@ -204,9 +204,9 @@ static void write_fields(FILE *h, var_list_t *fields)
>       if (!fields) return;
>   
>       LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
> -        if (!v || !v->type) continue;
> +        if (!v || !v->declspec.type) continue;
>   
> -        switch(type_get_type_detect_alias(v->type)) {
> +        switch(type_get_type_detect_alias(v->declspec.type)) {
>           case TYPE_STRUCT:
>           case TYPE_ENCAPSULATED_UNION:
>               nameless_struct_cnt++;
> @@ -220,12 +220,12 @@ static void write_fields(FILE *h, var_list_t *fields)
>       }
>   
>       LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
> -        if (!v || !v->type) continue;
> +        if (!v || !v->declspec.type) continue;
>   
>           indent(h, 0);
>           name = v->name;
>   
> -        switch(type_get_type_detect_alias(v->type)) {
> +        switch(type_get_type_detect_alias(v->declspec.type)) {
>           case TYPE_STRUCT:
>           case TYPE_ENCAPSULATED_UNION:
>               if(!v->name) {
> @@ -252,7 +252,7 @@ static void write_fields(FILE *h, var_list_t *fields)
>           default:
>               ;
>           }
> -        write_type_def_or_decl(h, v->type, TRUE, name);
> +        write_type_def_or_decl(h, v->declspec.type, TRUE, name);
>           fprintf(h, ";\n");
>       }
>   }
> @@ -697,7 +697,7 @@ void check_for_additional_prototype_types(type_t *type)
>           break;
>         }
>         if (vars) LIST_FOR_EACH_ENTRY( v, vars, const var_t, entry )
> -        check_for_additional_prototype_types(v->type);
> +        check_for_additional_prototype_types(v->declspec.type);
>       }
>   
>       if (type_is_alias(type))
> @@ -800,7 +800,7 @@ int is_const_decl(const var_t *var)
>     * declaration to mean that data isn't being instantiated. this appears
>     * to be a bug, but there is no benefit to being incompatible with MIDL,
>     * so we'll do the same thing */
> -  for (t = var->type; ; )
> +  for (t = var->declspec.type; ; )
>     {
>       if (is_attr(t->attrs, ATTR_CONST))
>         return TRUE;
> @@ -821,7 +821,7 @@ static void write_declaration(FILE *header, const var_t *v)
>     }
>     else
>     {
> -    switch (v->stgclass)
> +    switch (v->declspec.stgclass)
>       {
>         case STG_NONE:
>         case STG_REGISTER: /* ignored */
> @@ -833,7 +833,7 @@ static void write_declaration(FILE *header, const var_t *v)
>           fprintf(header, "extern ");
>           break;
>       }
> -    write_type_def_or_decl(header, v->type, FALSE, v->name);
> +    write_type_def_or_decl(header, v->declspec.type, FALSE, v->name);
>       fprintf(header, ";\n\n");
>     }
>   }
> @@ -850,7 +850,7 @@ static void write_library(FILE *header, const typelib_t *typelib)
>   const type_t* get_explicit_generic_handle_type(const var_t* var)
>   {
>       const type_t *t;
> -    for (t = var->type;
> +    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(t))
>           if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
> @@ -863,13 +863,13 @@ 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->type );
> +    const var_list_t *args = type_get_function_args( func->declspec.type );
>   
>       *explicit_fc = *implicit_fc = 0;
>       if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
>       {
>           if (!is_attr( var->attrs, ATTR_IN ) && is_attr( var->attrs, ATTR_OUT )) continue;
> -        if (type_get_type( var->type ) == TYPE_BASIC && type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
> +        if (type_get_type( var->declspec.type ) == TYPE_BASIC && type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
>           {
>               *explicit_fc = FC_BIND_PRIMITIVE;
>               return var;
> @@ -879,7 +879,7 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
>               *explicit_fc = FC_BIND_GENERIC;
>               return var;
>           }
> -        if (is_context_handle( var->type ))
> +        if (is_context_handle( var->declspec.type ))
>           {
>               *explicit_fc = FC_BIND_CONTEXT;
>               return var;
> @@ -888,8 +888,8 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
>   
>       if ((var = get_attrp( iface->attrs, ATTR_IMPLICIT_HANDLE )))
>       {
> -        if (type_get_type( var->type ) == TYPE_BASIC &&
> -            type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
> +        if (type_get_type( var->declspec.type ) == TYPE_BASIC &&
> +            type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
>               *implicit_fc = FC_BIND_PRIMITIVE;
>           else
>               *implicit_fc = FC_BIND_GENERIC;
> @@ -904,13 +904,13 @@ int has_out_arg_or_return(const var_t *func)
>   {
>       const var_t *var;
>   
> -    if (!is_void(type_function_get_rettype(func->type)))
> +    if (!is_void(type_function_get_rettype(func->declspec.type)))
>           return 1;
>   
> -    if (!type_get_function_args(func->type))
> +    if (!type_get_function_args(func->declspec.type))
>           return 0;
>   
> -    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> +    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
>           if (is_attr(var->attrs, ATTR_OUT))
>               return 1;
>   
> @@ -990,7 +990,7 @@ static int is_override_method(const type_t *iface, const type_t *child, const va
>   
>   static int is_aggregate_return(const var_t *func)
>   {
> -  enum type_type type = type_get_type(type_function_get_rettype(func->type));
> +  enum type_type type = type_get_type(type_function_get_rettype(func->declspec.type));
>     return type == TYPE_STRUCT || type == TYPE_UNION ||
>            type == TYPE_COCLASS || type == TYPE_INTERFACE;
>   }
> @@ -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->type))
> -          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
> +      if (type_get_function_args(func->declspec.type))
> +          LIST_FOR_EACH_ENTRY( arg, type_get_function_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->type))
> -          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
> +      if (type_get_function_args(func->declspec.type))
> +          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), const var_t, entry )
>                 fprintf(header, ",%s", arg->name);
>         fprintf(header, ")\n");
>       }
> @@ -1073,7 +1073,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
>           }
>           else fprintf(h, ",");
>       }
> -    write_type_decl(h, arg->type, arg->name);
> +    write_type_decl(h, arg->declspec.type, arg->name);
>       if (method == 2) {
>           const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE);
>           if (expr) {
> @@ -1085,7 +1085,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
>                       expr_t bstr;
>   
>                       /* Fixup the expression type for a BSTR like midl does. */
> -                    if (get_type_vt(arg->type) == VT_BSTR && expr->type == EXPR_STRLIT)
> +                    if (get_type_vt(arg->declspec.type) == VT_BSTR && expr->type == EXPR_STRLIT)
>                       {
>                           bstr = *expr;
>                           bstr.type = EXPR_WSTRLIT;
> @@ -1114,8 +1114,8 @@ 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->type->attrs, ATTR_CALLCONV);
> -      const var_list_t *args = type_get_function_args(func->type);
> +      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_t *arg;
>   
>         if (!callconv) callconv = "STDMETHODCALLTYPE";
> @@ -1125,11 +1125,11 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
>   
>           indent(header, 0);
>           fprintf(header, "virtual ");
> -        write_type_decl_left(header, type_function_get_rettype(func->type));
> +        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>           fprintf(header, "* %s %s(\n", callconv, get_name(func));
>           ++indentation;
>           indent(header, 0);
> -        write_type_decl_left(header, type_function_get_rettype(func->type));
> +        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>           fprintf(header, " *__ret");
>           --indentation;
>           if (args) {
> @@ -1139,7 +1139,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
>           fprintf(header, ") = 0;\n");
>   
>           indent(header, 0);
> -        write_type_decl_left(header, type_function_get_rettype(func->type));
> +        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>           fprintf(header, " %s %s(\n", callconv, get_name(func));
>           write_args(header, args, iface->name, 2, TRUE);
>           fprintf(header, ")\n");
> @@ -1147,7 +1147,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
>           fprintf(header, "{\n");
>           ++indentation;
>           indent(header, 0);
> -        write_type_decl_left(header, type_function_get_rettype(func->type));
> +        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>           fprintf(header, " __ret;\n");
>           indent(header, 0);
>           fprintf(header, "return *%s(&__ret", get_name(func));
> @@ -1164,7 +1164,7 @@ static void write_cpp_method_def(FILE *header, const type_t *iface)
>   
>         indent(header, 0);
>         fprintf(header, "virtual ");
> -      write_type_decl_left(header, type_function_get_rettype(func->type));
> +      write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>         fprintf(header, " %s %s(\n", callconv, get_name(func));
>         write_args(header, args, iface->name, 2, TRUE);
>         fprintf(header, ") = 0;\n");
> @@ -1201,25 +1201,25 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
>         const var_t *arg;
>   
>         fprintf(header, "static FORCEINLINE ");
> -      write_type_decl_left(header, type_function_get_rettype(func->type));
> +      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->type), name, 1, FALSE);
> +      write_args(header, type_get_function_args(func->declspec.type), name, 1, FALSE);
>         fprintf(header, ") {\n");
>         ++indentation;
>         if (!is_aggregate_return(func)) {
>           indent(header, 0);
>           fprintf(header, "%sThis->lpVtbl->%s(This",
> -                is_void(type_function_get_rettype(func->type)) ? "" : "return ",
> +                is_void(type_function_get_rettype(func->declspec.type)) ? "" : "return ",
>                   get_vtbl_entry_name(iface, func));
>         } else {
>           indent(header, 0);
> -        write_type_decl_left(header, type_function_get_rettype(func->type));
> +        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>           fprintf(header, " __ret;\n");
>           indent(header, 0);
>           fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_vtbl_entry_name(iface, func));
>         }
> -      if (type_get_function_args(func->type))
> -          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
> +      if (type_get_function_args(func->declspec.type))
> +          LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), const var_t, entry )
>                 fprintf(header, ",%s", arg->name);
>         fprintf(header, ");\n");
>         --indentation;
> @@ -1245,10 +1245,10 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
>         first_iface = 0;
>       }
>       if (!is_callas(func->attrs)) {
> -      const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
> +      const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
>         if (!callconv) callconv = "STDMETHODCALLTYPE";
>         indent(header, 0);
> -      write_type_decl_left(header, type_function_get_rettype(func->type));
> +      write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>         if (is_aggregate_return(func))
>           fprintf(header, " *");
>         if (is_inherited_method(iface, func))
> @@ -1261,13 +1261,13 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char
>         if (is_aggregate_return(func)) {
>           fprintf(header, ",\n");
>           indent(header, 0);
> -        write_type_decl_left(header, type_function_get_rettype(func->type));
> +        write_type_decl_left(header, type_function_get_rettype(func->declspec.type));
>           fprintf(header, " *__ret");
>         }
>         --indentation;
> -      if (type_get_function_args(func->type)) {
> +      if (type_get_function_args(func->declspec.type)) {
>           fprintf(header, ",\n");
> -        write_args(header, type_get_function_args(func->type), name, 0, TRUE);
> +        write_args(header, type_get_function_args(func->declspec.type), name, 0, TRUE);
>         }
>         fprintf(header, ");\n");
>         fprintf(header, "\n");
> @@ -1294,12 +1294,12 @@ static void write_method_proto(FILE *header, const type_t *iface)
>       const var_t *func = stmt->u.var;
>   
>       if (is_callas(func->attrs)) {
> -      const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
> +      const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
>         if (!callconv) callconv = "STDMETHODCALLTYPE";
>         /* proxy prototype */
> -      write_type_decl_left(header, type_function_get_rettype(func->type));
> +      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->type), iface->name, 1, TRUE);
> +      write_args(header, type_get_function_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));
> @@ -1332,12 +1332,12 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
>         if (&stmt2->entry != type_iface_get_stmts(iface)) {
>           const var_t *m = stmt2->u.var;
>           /* proxy prototype - use local prototype */
> -        write_type_decl_left(fp, type_function_get_rettype(m->type));
> +        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->type), iface->name, 1, TRUE);
> +        write_args(fp, type_get_function_args(m->declspec.type), iface->name, 1, TRUE);
>           fprintf(fp, ")");
>           if (body) {
> -          type_t *rt = type_function_get_rettype(m->type);
> +          type_t *rt = type_function_get_rettype(m->declspec.type);
>             fprintf(fp, "\n{\n");
>             fprintf(fp, "    %s\n", comment);
>             if (rt->name && strcmp(rt->name, "HRESULT") == 0)
> @@ -1354,9 +1354,9 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
>           else
>             fprintf(fp, ";\n");
>           /* stub prototype - use remotable prototype */
> -        write_type_decl_left(fp, type_function_get_rettype(func->type));
> +        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->type), iface->name, 1, TRUE);
> +        write_args(fp, type_get_function_args(func->declspec.type), iface->name, 1, TRUE);
>           fprintf(fp, ")");
>           if (body)
>             /* Remotable methods must all return HRESULTs.  */
> @@ -1402,15 +1402,15 @@ void write_local_stubs(const statement_list_t *stmts)
>   
>   static void write_function_proto(FILE *header, const type_t *iface, const var_t *fun, const char *prefix)
>   {
> -  const char *callconv = get_attrp(fun->type->attrs, ATTR_CALLCONV);
> +  const char *callconv = get_attrp(fun->declspec.type->attrs, ATTR_CALLCONV);
>   
>     if (!callconv) callconv = "__cdecl";
>     /* FIXME: do we need to handle call_as? */
> -  write_type_decl_left(header, type_function_get_rettype(fun->type));
> +  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->type))
> -    write_args(header, type_get_function_args(fun->type), iface->name, 0, TRUE);
> +  if (type_get_function_args(fun->declspec.type))
> +    write_args(header, type_get_function_args(fun->declspec.type), iface->name, 0, TRUE);
>     else
>       fprintf(header, "    void");
>     fprintf(header, ");\n\n");
> @@ -1536,7 +1536,7 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
>     if (var)
>     {
>         fprintf(header, "extern ");
> -      write_type_decl( header, var->type, var->name );
> +      write_type_decl( header, var->declspec.type, var->name );
>         fprintf(header, ";\n");
>     }
>     if (old_names)
> @@ -1745,7 +1745,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
>           fprintf(header, "%s\n", stmt->u.str);
>           break;
>         case STMT_DECLARATION:
> -        if (iface && type_get_type(stmt->u.var->type) == TYPE_FUNCTION)
> +        if (iface && type_get_type(stmt->u.var->declspec.type) == TYPE_FUNCTION)
>           {
>             if (!ignore_funcs)
>             {
> diff --git a/tools/widl/parser.y b/tools/widl/parser.y
> index 1e5c8e181d..50e42291bd 100644
> --- a/tools/widl/parser.y
> +++ b/tools/widl/parser.y
> @@ -52,13 +52,6 @@ struct _import_t
>     int import_performed;
>   };
>   
> -typedef struct _decl_spec_t
> -{
> -  type_t *type;
> -  attr_list_t *attrs;
> -  enum storage_class stgclass;
> -} decl_spec_t;
> -
>   typelist_t incomplete_types = LIST_INIT(incomplete_types);
>   
>   static void fix_incomplete(void);
> @@ -651,10 +644,10 @@ enum_list: enum					{ if (!$1->eval)
>   
>   enum:	  ident '=' expr_int_const		{ $$ = reg_const($1);
>   						  $$->eval = $3;
> -                                                  $$->type = type_new_int(TYPE_BASIC_INT, 0);
> +                                                  $$->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
>   						}
>   	| ident					{ $$ = reg_const($1);
> -                                                  $$->type = type_new_int(TYPE_BASIC_INT, 0);
> +                                                  $$->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
>   						}
>   	;
>   
> @@ -740,7 +733,7 @@ field:	  m_attributes decl_spec struct_declarator_list ';'
>   						  $$ = set_var_types($1, $2, $3);
>   						}
>   	| m_attributes uniondef ';'		{ var_t *v = make_var(NULL);
> -						  v->type = $2; v->attrs = $1;
> +						  v->declspec.type = $2; v->attrs = $1;
>   						  $$ = append_var(NULL, v);
>   						}
>   	;
> @@ -764,13 +757,13 @@ s_field:  m_attributes decl_spec declarator	{ $$ = declare_var(check_field_attrs
>   						  free($3);
>   						}
>   	| m_attributes structdef		{ var_t *v = make_var(NULL);
> -						  v->type = $2; v->attrs = $1;
> +						  v->declspec.type = $2; v->attrs = $1;
>   						  $$ = v;
>   						}
>   	;
>   
>   funcdef: declaration				{ $$ = $1;
> -						  if (type_get_type($$->type) != TYPE_FUNCTION)
> +						  if (type_get_type($$->declspec.type) != TYPE_FUNCTION)
>   						    error_loc("only methods may be declared inside the methods section of a dispinterface\n");
>   						  check_function_attrs($$->name, $$->attrs);
>   						}
> @@ -1540,19 +1533,19 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
>     }
>   
>     /* add type onto the end of the pointers in pident->type */
> -  v->type = append_chain_type(decl ? decl->type : NULL, type);
> -  v->stgclass = decl_spec->stgclass;
> +  v->declspec.type = append_chain_type(decl ? decl->type : NULL, type);
> +  v->declspec.stgclass = decl_spec->stgclass;
>     v->attrs = attrs;
>   
>     /* check for pointer attribute being applied to non-pointer, non-array
>      * type */
> -  if (!is_array(v->type))
> +  if (!is_array(v->declspec.type))
>     {
>       int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
>       const type_t *ptr = NULL;
>       /* pointer attributes on the left side of the type belong to the function
>        * pointer, if one is being declared */
> -    type_t **pt = func_type ? &func_type : &v->type;
> +    type_t **pt = func_type ? &func_type : &v->declspec.type;
>       for (ptr = *pt; ptr && !ptr_attr; )
>       {
>         ptr_attr = get_attrv(ptr->attrs, ATTR_POINTERTYPE);
> @@ -1585,7 +1578,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
>     {
>       type_t *t = type;
>   
> -    if (!is_ptr(v->type) && !is_array(v->type))
> +    if (!is_ptr(v->declspec.type) && !is_array(v->declspec.type))
>         error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
>                   v->name);
>   
> @@ -1611,15 +1604,15 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
>   
>     if (is_attr(v->attrs, ATTR_V1ENUM))
>     {
> -    if (type_get_type_detect_alias(v->type) != TYPE_ENUM)
> +    if (type_get_type_detect_alias(v->declspec.type) != TYPE_ENUM)
>         error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
>     }
>   
> -  if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->type))
> +  if (is_attr(v->attrs, ATTR_RANGE) && !is_allowed_range_type(v->declspec.type))
>       error_loc("'%s': [range] attribute applied to non-integer type\n",
>                 v->name);
>   
> -  ptype = &v->type;
> +  ptype = &v->declspec.type;
>     if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
>     {
>       if (dim->type != EXPR_VOID)
> @@ -1649,7 +1642,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
>         error_loc("%s: too many expressions in size_is attribute\n", v->name);
>     }
>   
> -  ptype = &v->type;
> +  ptype = &v->declspec.type;
>     if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry)
>     {
>       if (dim->type != EXPR_VOID)
> @@ -1681,28 +1674,28 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
>     if (func_type)
>     {
>       type_t *ft, *t;
> -    type_t *return_type = v->type;
> -    v->type = func_type;
> -    for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
> +    type_t *return_type = v->declspec.type;
> +    v->declspec.type = func_type;
> +    for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref(ft))
>         ;
>       assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
>       ft->details.function->retval = make_var(xstrdup("_RetVal"));
> -    ft->details.function->retval->type = return_type;
> +    ft->details.function->retval->declspec.type = return_type;
>       /* move calling convention attribute, if present, from pointer nodes to
>        * function node */
> -    for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
> +    for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref(t))
>         ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
>     }
>     else
>     {
>       type_t *t;
> -    for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t))
> +    for (t = v->declspec.type; is_ptr(t); t = type_pointer_get_ref(t))
>         if (is_attr(t->attrs, ATTR_CALLCONV))
>           error_loc("calling convention applied to non-function-pointer type\n");
>     }
>   
>     if (decl->bits)
> -    v->type = type_new_bitfield(v->type, decl->bits);
> +    v->declspec.type = type_new_bitfield(v->declspec.type, decl->bits);
>   
>     return v;
>   }
> @@ -1770,10 +1763,9 @@ var_t *make_var(char *name)
>   {
>     var_t *v = xmalloc(sizeof(var_t));
>     v->name = name;
> -  v->type = NULL;
> +  init_declspec(&v->declspec, NULL);
>     v->attrs = NULL;
>     v->eval = NULL;
> -  v->stgclass = STG_NONE;
>     init_loc_info(&v->loc_info);
>     return v;
>   }
> @@ -1782,10 +1774,9 @@ static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
>   {
>     var_t *v = xmalloc(sizeof(var_t));
>     v->name = name;
> -  v->type = src->type;
> +  v->declspec = src->declspec;
>     v->attrs = map_attrs(src->attrs, attr_filter);
>     v->eval = src->eval;
> -  v->stgclass = src->stgclass;
>     v->loc_info = src->loc_info;
>     return v;
>   }
> @@ -2010,7 +2001,7 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
>                       cur->loc_info.line_number);
>   
>         name = declare_var(attrs, decl_spec, decl, 0);
> -      cur = type_new_alias(name->type, name->name);
> +      cur = type_new_alias(name->declspec.type, name->name);
>         cur->attrs = attrs;
>   
>         if (is_incomplete(cur))
> @@ -2285,10 +2276,10 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
>       if (attr->type == ATTR_IMPLICIT_HANDLE)
>       {
>           const var_t *var = attr->u.pval;
> -        if (type_get_type( var->type) == TYPE_BASIC &&
> -            type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
> +        if (type_get_type( var->declspec.type) == TYPE_BASIC &&
> +            type_basic_get_type( var->declspec.type ) == TYPE_BASIC_HANDLE)
>               continue;
> -        if (is_aliaschain_attr( var->type, ATTR_HANDLE ))
> +        if (is_aliaschain_attr( var->declspec.type, ATTR_HANDLE ))
>               continue;
>         error_loc("attribute %s requires a handle type in interface %s\n",
>                   allowed_attr[attr->type].display_name, name);
> @@ -2520,7 +2511,7 @@ static void check_remoting_fields(const var_t *var, type_t *type);
>   static void check_field_common(const type_t *container_type,
>                                  const char *container_name, const var_t *arg)
>   {
> -    type_t *type = arg->type;
> +    type_t *type = arg->declspec.type;
>       int more_to_do;
>       const char *container_type_name;
>       const char *var_type;
> @@ -2550,7 +2541,7 @@ static void check_field_common(const type_t *container_type,
>       }
>   
>       if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
> -        (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
> +        (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->declspec.type, ATTR_STRING)))
>           error_loc_info(&arg->loc_info,
>                          "string and length_is specified for argument %s are mutually exclusive attributes\n",
>                          arg->name);
> @@ -2694,7 +2685,7 @@ static void check_remoting_fields(const var_t *var, type_t *type)
>           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);
> +        if (field->declspec.type) check_field_common(type, type->name, field);
>   }
>   
>   /* checks that arguments for a function make sense for marshalling and unmarshalling */
> @@ -2703,9 +2694,9 @@ static void check_remoting_args(const var_t *func)
>       const char *funcname = func->name;
>       const var_t *arg;
>   
> -    if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
> +    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->type;
> +        const type_t *type = arg->declspec.type;
>   
>           /* check that [out] parameters have enough pointer levels */
>           if (is_attr(arg->attrs, ATTR_OUT))
> @@ -2745,16 +2736,16 @@ static void check_remoting_args(const var_t *func)
>               }
>           }
>   
> -        check_field_common(func->type, funcname, arg);
> +        check_field_common(func->declspec.type, funcname, arg);
>       }
>   
> -    if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
> +    if (type_get_type(type_function_get_rettype(func->declspec.type)) != TYPE_VOID)
>       {
>           var_t var;
>           var = *func;
> -        var.type = type_function_get_rettype(func->type);
> +        var.declspec.type = type_function_get_rettype(func->declspec.type);
>           var.name = xstrdup("return value");
> -        check_field_common(func->type, funcname, &var);
> +        check_field_common(func->declspec.type, funcname, &var);
>           free(var.name);
>       }
>   }
> @@ -2771,8 +2762,8 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
>            * function */
>           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);
> -        type_function_add_head_arg(func->type, idl_handle);
> +        idl_handle->declspec.type = find_type_or_error("handle_t", 0);
> +        type_function_add_head_arg(func->declspec.type, idl_handle);
>       }
>   }
>   
> @@ -2853,7 +2844,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;
>   
> -        args = func->type->details.function->args;
> +        args = func->declspec.type->details.function->args;
>           if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
>           {
>               if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
> @@ -2863,15 +2854,15 @@ static void check_async_uuid(type_t *iface)
>           }
>   
>           begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
> -        begin_func->type = type_new_function(begin_args);
> -        begin_func->type->attrs = func->attrs;
> -        begin_func->type->details.function->retval = func->type->details.function->retval;
> +        begin_func->declspec.type = type_new_function(begin_args);
> +        begin_func->declspec.type->attrs = func->attrs;
> +        begin_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
>           stmts = append_statement(stmts, make_statement_declaration(begin_func));
>   
>           finish_func = copy_var(func, concat_str("Finish_", func->name), NULL);
> -        finish_func->type = type_new_function(finish_args);
> -        finish_func->type->attrs = func->attrs;
> -        finish_func->type->details.function->retval = func->type->details.function->retval;
> +        finish_func->declspec.type = type_new_function(finish_args);
> +        finish_func->declspec.type->attrs = func->attrs;
> +        finish_func->declspec.type->details.function->retval = func->declspec.type->details.function->retval;
>           stmts = append_statement(stmts, make_statement_declaration(finish_func));
>       }
>   
> @@ -2923,10 +2914,10 @@ 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;
> -        if (func->type->details.function->args)
> -          LIST_FOR_EACH_ENTRY( v, func->type->details.function->args, const var_t, entry )
> -            check_for_additional_prototype_types(v->type);
> -        check_for_additional_prototype_types(type_function_get_rettype(func->type));
> +        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);
> +        check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
>         }
>       }
>     }
> @@ -2974,16 +2965,16 @@ static statement_t *make_statement_declaration(var_t *var)
>   {
>       statement_t *stmt = make_statement(STMT_DECLARATION);
>       stmt->u.var = var;
> -    if (var->stgclass == STG_EXTERN && var->eval)
> +    if (var->declspec.stgclass == STG_EXTERN && var->eval)
>           warning("'%s' initialised and declared extern\n", var->name);
>       if (is_const_decl(var))
>       {
>           if (var->eval)
>               reg_const(var);
>       }
> -    else if (type_get_type(var->type) == TYPE_FUNCTION)
> +    else if (type_get_type(var->declspec.type) == TYPE_FUNCTION)
>           check_function_attrs(var->name, var->attrs);
> -    else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER)
> +    else if (var->declspec.stgclass == STG_NONE || var->declspec.stgclass == STG_REGISTER)
>           error_loc("instantiation of data is illegal\n");
>       return stmt;
>   }
> diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c
> index ef52e35a4c..0b37cc9758 100644
> --- a/tools/widl/proxy.c
> +++ b/tools/widl/proxy.c
> @@ -105,15 +105,15 @@ static void clear_output_vars( const var_list_t *args )
>     {
>         if (is_attr(arg->attrs, ATTR_IN)) continue;
>         if (!is_attr(arg->attrs, ATTR_OUT)) continue;
> -      if (is_ptr(arg->type))
> +      if (is_ptr(arg->declspec.type))
>         {
> -          if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_BASIC) continue;
> -          if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_ENUM) continue;
> +          if (type_get_type(type_pointer_get_ref(arg->declspec.type)) == TYPE_BASIC) continue;
> +          if (type_get_type(type_pointer_get_ref(arg->declspec.type)) == TYPE_ENUM) continue;
>         }
>         print_proxy( "if (%s) MIDL_memset( %s, 0, ", arg->name, arg->name );
> -      if (is_array(arg->type) && type_array_has_conformance(arg->type))
> +      if (is_array(arg->declspec.type) && type_array_has_conformance(arg->declspec.type))
>         {
> -          write_expr( proxy, type_array_get_conformance(arg->type), 1, 1, NULL, NULL, "" );
> +          write_expr( proxy, type_array_get_conformance(arg->declspec.type), 1, 1, NULL, NULL, "" );
>             fprintf( proxy, " * " );
>         }
>         fprintf( proxy, "sizeof( *%s ));\n", arg->name );
> @@ -147,7 +147,7 @@ static int need_delegation_indirect(const type_t *iface)
>   static void free_variable( const var_t *arg, const char *local_var_prefix )
>   {
>     unsigned int type_offset = arg->typestring_offset;
> -  type_t *type = arg->type;
> +  type_t *type = arg->declspec.type;
>   
>     write_parameter_conf_or_var_exprs(proxy, indent, local_var_prefix, PHASE_FREE, arg, FALSE);
>   
> @@ -191,18 +191,18 @@ static void proxy_free_variables( var_list_t *args, const char *local_var_prefix
>   static void gen_proxy(type_t *iface, const var_t *func, int idx,
>                         unsigned int proc_offset)
>   {
> -  var_t *retval = type_function_get_retval(func->type);
> -  int has_ret = !is_void(retval->type);
> +  var_t *retval = type_function_get_retval(func->declspec.type);
> +  int has_ret = !is_void(retval->declspec.type);
>     int has_full_pointer = is_full_pointer_function(func);
> -  const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV);
> -  const var_list_t *args = type_get_function_args(func->type);
> +  const char *callconv = get_attrp(func->declspec.type->attrs, ATTR_CALLCONV);
> +  const var_list_t *args = type_get_function_args(func->declspec.type);
>     if (!callconv) callconv = "STDMETHODCALLTYPE";
>   
>     indent = 0;
>     if (is_interpreted_func( iface, func ))
>     {
>         if (get_stub_mode() == MODE_Oif && !is_callas( func->attrs )) return;
> -      write_type_decl_left(proxy, retval->type);
> +      write_type_decl_left(proxy, retval->declspec.type);
>         print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
>         write_args(proxy, args, iface->name, 1, TRUE);
>         print_proxy( ")\n");
> @@ -219,7 +219,7 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
>     print_proxy( "}\n");
>     print_proxy( "\n");
>   
> -  write_type_decl_left(proxy, retval->type);
> +  write_type_decl_left(proxy, retval->declspec.type);
>     print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func));
>     write_args(proxy, args, iface->name, 1, TRUE);
>     print_proxy( ")\n");
> @@ -229,12 +229,12 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
>     /* local variables */
>     if (has_ret) {
>       print_proxy( "%s", "" );
> -    write_type_decl(proxy, retval->type, retval->name);
> +    write_type_decl(proxy, retval->declspec.type, retval->name);
>       fprintf( proxy, ";\n" );
>     }
>     print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
>     if (has_ret) {
> -    if (decl_indirect(retval->type))
> +    if (decl_indirect(retval->declspec.type))
>           print_proxy("void *_p_%s = &%s;\n", retval->name, retval->name);
>     }
>     print_proxy( "\n");
> @@ -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->type) );
> +  clear_output_vars( type_get_function_args(func->declspec.type) );
>   
>     print_proxy( "RpcTryExcept\n" );
>     print_proxy( "{\n" );
> @@ -279,9 +279,9 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx,
>   
>     if (has_ret)
>     {
> -      if (decl_indirect(retval->type))
> +      if (decl_indirect(retval->declspec.type))
>             print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", retval->name, retval->name);
> -      else if (is_ptr(retval->type) || is_array(retval->type))
> +      else if (is_ptr(retval->declspec.type) || is_array(retval->declspec.type))
>             print_proxy("%s = 0;\n", retval->name);
>         write_remoting_arguments(proxy, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL);
>     }
> @@ -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->type), "" );
> +    proxy_free_variables( type_get_function_args(func->declspec.type), "" );
>       print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" );
>       indent--;
>     }
> @@ -320,7 +320,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
>                        unsigned int proc_offset)
>   {
>     const var_t *arg;
> -  int has_ret = !is_void(type_function_get_rettype(func->type));
> +  int has_ret = !is_void(type_function_get_rettype(func->declspec.type));
>     int has_full_pointer = is_full_pointer_function(func);
>   
>     if (is_interpreted_func( iface, func )) return;
> @@ -389,10 +389,10 @@ 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->type))
> +  if (type_get_function_args(func->declspec.type))
>     {
> -      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry )
> -          fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name);
> +      LIST_FOR_EACH_ENTRY( arg, type_get_function_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");
>     fprintf(proxy, "\n");
> @@ -401,7 +401,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
>   
>     write_remoting_arguments(proxy, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
>   
> -  if (!is_void(type_function_get_rettype(func->type)))
> +  if (!is_void(type_function_get_rettype(func->declspec.type)))
>       write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
>   
>     print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &__frame->_StubMsg);\n");
> @@ -410,7 +410,7 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
>     fprintf(proxy, "\n");
>   
>     /* marshall the return value */
> -  if (!is_void(type_function_get_rettype(func->type)))
> +  if (!is_void(type_function_get_rettype(func->declspec.type)))
>       write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
>   
>     indent--;
> @@ -432,16 +432,16 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
>   
>   static void gen_stub_thunk( type_t *iface, const var_t *func, unsigned int proc_offset )
>   {
> -    int has_ret = !is_void( type_function_get_rettype( func->type ));
> +    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->type );
> +    const var_list_t *args = type_get_function_args( func->declspec.type );
>   
>       indent = 0;
>       print_proxy( "void __RPC_API %s_%s_Thunk( PMIDL_STUB_MESSAGE pStubMsg )\n",
>                    iface->name, get_name(func) );
>       print_proxy( "{\n");
>       indent++;
> -    write_func_param_struct( proxy, iface, func->type,
> +    write_func_param_struct( proxy, iface, func->declspec.type,
>                                "*pParamStruct = (struct _PARAM_STRUCT *)pStubMsg->StackTop", has_ret );
>       print_proxy( "%s%s_%s_Stub( pParamStruct->This",
>                    has_ret ? "pParamStruct->_RetVal = " : "", iface->name, callas->name );
> @@ -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->type->details.function->idx;
> +      int idx = func->declspec.type->details.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->type->details.function->idx;
> +                  idx = m->declspec.type->details.function->idx;
>                     break;
>                 }
>             }
> diff --git a/tools/widl/server.c b/tools/widl/server.c
> index 59c17d661f..fb14dd87bc 100644
> --- a/tools/widl/server.c
> +++ b/tools/widl/server.c
> @@ -55,7 +55,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
>       unsigned char explicit_fc, implicit_fc;
>       int has_full_pointer = is_full_pointer_function(func);
>       const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
> -    type_t *ret_type = type_function_get_rettype(func->type);
> +    type_t *ret_type = type_function_get_rettype(func->declspec.type);
>   
>       if (is_interpreted_func( iface, func )) return;
>   
> @@ -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->type))
> +    if (type_get_function_args(func->declspec.type))
>       {
>           print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
>           indent++;
> @@ -166,31 +166,31 @@ 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->type))
> +    if (type_get_function_args(func->declspec.type))
>       {
>           int first_arg = 1;
>   
>           fprintf(server, "(\n");
>           indent++;
> -        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> +        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
>           {
>               if (first_arg)
>                   first_arg = 0;
>               else
>                   fprintf(server, ",\n");
> -            if (is_context_handle(var->type))
> +            if (is_context_handle(var->declspec.type))
>               {
>                   /* if the context_handle attribute appears in the chain of types
>                    * without pointers being followed, then the context handle must
>                    * be direct, otherwise it is a pointer */
> -                const char *ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? "*" : "";
> +                const char *ch_ptr = is_aliaschain_attr(var->declspec.type, ATTR_CONTEXTHANDLE) ? "*" : "";
>                   print_server("(");
> -                write_type_decl_left(server, var->type);
> +                write_type_decl_left(server, var->declspec.type);
>                   fprintf(server, ")%sNDRSContextValue(__frame->%s)", ch_ptr, var->name);
>               }
>               else
>               {
> -                print_server("%s__frame->%s", is_array(var->type) && !type_array_is_decl_as_ptr(var->type) ? "*" : "", var->name);
> +                print_server("%s__frame->%s", is_array(var->declspec.type) && !type_array_is_decl_as_ptr(var->declspec.type) ? "*" : "", var->name);
>               }
>           }
>           fprintf(server, ");\n");
> diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
> index a121364415..f685f7156a 100644
> --- a/tools/widl/typegen.c
> +++ b/tools/widl/typegen.c
> @@ -379,13 +379,13 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
>   
>   static int cant_be_null(const var_t *v)
>   {
> -    switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS))
> +    switch (typegen_detect_type(v->declspec.type, v->attrs, TDT_IGNORE_STRINGS))
>       {
>       case TGT_ARRAY:
> -        if (!type_array_is_decl_as_ptr( v->type )) return 0;
> +        if (!type_array_is_decl_as_ptr( v->declspec.type )) return 0;
>           /* fall through */
>       case TGT_POINTER:
> -        return (get_pointer_fc(v->type, v->attrs, TRUE) == FC_RP);
> +        return (get_pointer_fc(v->declspec.type, v->attrs, TRUE) == FC_RP);
>       case TGT_CTXT_HANDLE_POINTER:
>           return TRUE;
>       default:
> @@ -405,7 +405,7 @@ static int get_padding(const var_list_t *fields)
>   
>       LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
>       {
> -        type_t *ft = f->type;
> +        type_t *ft = f->declspec.type;
>           unsigned int align = 0;
>           unsigned int size = type_memsize_and_alignment(ft, &align);
>           align = clamp_align(align);
> @@ -422,7 +422,7 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
>       unsigned int stack_size;
>       int by_val;
>   
> -    switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
> +    switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES ))
>       {
>       case TGT_BASIC:
>       case TGT_ENUM:
> @@ -430,7 +430,7 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
>       case TGT_STRUCT:
>       case TGT_UNION:
>       case TGT_USER_TYPE:
> -        stack_size = type_memsize( var->type );
> +        stack_size = type_memsize( var->declspec.type );
>           by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */
>           break;
>       default:
> @@ -495,14 +495,14 @@ unsigned char get_struct_fc(const type_t *type)
>   
>     if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry )
>     {
> -    type_t *t = field->type;
> +    type_t *t = field->declspec.type;
>       enum typegen_type typegen_type;
>   
>       typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
>   
>       if (typegen_type == TGT_ARRAY && !type_array_is_decl_as_ptr(t))
>       {
> -        if (is_string_type(field->attrs, field->type))
> +        if (is_string_type(field->attrs, field->declspec.type))
>           {
>               if (is_conformant_array(t))
>                   has_conformance = 1;
> @@ -510,10 +510,10 @@ unsigned char get_struct_fc(const type_t *type)
>               continue;
>           }
>   
> -        if (is_array(type_array_get_element(field->type)))
> +        if (is_array(type_array_get_element(field->declspec.type)))
>               return FC_BOGUS_STRUCT;
>   
> -        if (type_array_has_conformance(field->type))
> +        if (type_array_has_conformance(field->declspec.type))
>           {
>               has_conformance = 1;
>               if (list_next(fields, &field->entry))
> @@ -721,7 +721,7 @@ static int type_has_pointers(const type_t *type)
>           const var_t *field;
>           if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
>           {
> -            if (type_has_pointers(field->type))
> +            if (type_has_pointers(field->declspec.type))
>                   return TRUE;
>           }
>           break;
> @@ -733,7 +733,7 @@ static int type_has_pointers(const type_t *type)
>           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))
> +            if (field->declspec.type && type_has_pointers(field->declspec.type))
>                   return TRUE;
>           }
>           break;
> @@ -775,7 +775,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
>           const var_t *field;
>           if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
>           {
> -            if (type_has_full_pointer(field->type, field->attrs, FALSE))
> +            if (type_has_full_pointer(field->declspec.type, field->attrs, FALSE))
>                   return TRUE;
>           }
>           break;
> @@ -787,7 +787,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
>           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, field->attrs, FALSE))
> +            if (field->declspec.type && type_has_full_pointer(field->declspec.type, field->attrs, FALSE))
>                   return TRUE;
>           }
>           break;
> @@ -907,16 +907,16 @@ static void write_var_init(FILE *file, int indent, const type_t *t, const char *
>   
>   void write_parameters_init(FILE *file, int indent, const var_t *func, const char *local_var_prefix)
>   {
> -    const var_t *var = type_function_get_retval(func->type);
> +    const var_t *var = type_function_get_retval(func->declspec.type);
>   
> -    if (!is_void(var->type))
> -        write_var_init(file, indent, var->type, var->name, local_var_prefix);
> +    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->type))
> +    if (!type_get_function_args(func->declspec.type))
>           return;
>   
> -    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> -        write_var_init(file, indent, var->type, var->name, local_var_prefix);
> +    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
> +        write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
>   
>       fprintf(file, "\n");
>   }
> @@ -980,14 +980,14 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
>       if (is_out)    *flags |= IsOut;
>       if (is_return) *flags |= IsReturn;
>   
> -    if (!is_string_type( var->attrs, var->type ))
> -        buffer_size = get_required_buffer_size_type( var->type, NULL, var->attrs, TRUE, &alignment );
> +    if (!is_string_type( var->attrs, var->declspec.type ))
> +        buffer_size = get_required_buffer_size_type( var->declspec.type, NULL, var->attrs, TRUE, &alignment );
>   
> -    switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
> +    switch (typegen_detect_type( var->declspec.type, var->attrs, TDT_ALL_TYPES ))
>       {
>       case TGT_BASIC:
>           *flags |= IsBasetype;
> -        fc = get_basic_fc_signed( var->type );
> +        fc = get_basic_fc_signed( var->declspec.type );
>           if (fc == FC_BIND_PRIMITIVE)
>           {
>               buffer_size = 4;  /* actually 0 but avoids setting MustSize */
> @@ -996,7 +996,7 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
>           break;
>       case TGT_ENUM:
>           *flags |= IsBasetype;
> -        fc = get_enum_fc( var->type );
> +        fc = get_enum_fc( var->declspec.type );
>           break;
>       case TGT_RANGE:
>           *flags |= IsByValue;
> @@ -1011,19 +1011,19 @@ 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->type) && var->type->details.array.ptr_tfsoff &&
> -            get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
> +        if (type_array_is_decl_as_ptr(var->declspec.type) && var->declspec.type->details.array.ptr_tfsoff &&
> +            get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
>           {
> -            *typestring_offset = var->type->typestring_offset;
> +            *typestring_offset = var->declspec.type->typestring_offset;
>               *flags |= IsSimpleRef;
>           }
>           break;
>       case TGT_STRING:
>           *flags |= MustFree;
> -        if (is_declptr( var->type ) && get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
> +        if (is_declptr( var->declspec.type ) && get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
>           {
>               /* skip over pointer description straight to string description */
> -            if (is_conformant_array( var->type )) *typestring_offset += 4;
> +            if (is_conformant_array( var->declspec.type )) *typestring_offset += 4;
>               else *typestring_offset += 2;
>               *flags |= IsSimpleRef;
>           }
> @@ -1036,9 +1036,9 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
>           buffer_size = 20;
>           break;
>       case TGT_POINTER:
> -        if (get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP)
> +        if (get_pointer_fc( var->declspec.type, var->attrs, !is_return ) == FC_RP)
>           {
> -            const type_t *ref = type_pointer_get_ref( var->type );
> +            const type_t *ref = type_pointer_get_ref( var->declspec.type );
>   
>               if (!is_string_type( var->attrs, ref ))
>                   buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment );
> @@ -1128,8 +1128,8 @@ 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->type );
> -    var_t *retval = type_function_get_retval( func->type );
> +    var_list_t *args = type_get_function_args( func->declspec.type );
> +    var_t *retval = type_function_get_retval( func->declspec.type );
>       unsigned char oi2_flags = 0x40;  /* HasExtensions */
>       unsigned short flags;
>       unsigned int stack_size, typestring_offset;
> @@ -1144,7 +1144,7 @@ static unsigned char get_func_oi2_flags( const var_t *func )
>           }
>       }
>   
> -    if (!is_void( retval->type ))
> +    if (!is_void( retval->declspec.type ))
>       {
>           oi2_flags |= 0x04;  /* HasRet */
>           get_parameter_fc( retval, 1, &flags, &stack_size, &typestring_offset );
> @@ -1198,8 +1198,8 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
>   
>       if (!is_in && !is_out) is_in = TRUE;
>   
> -    if (type_get_type(var->type) == TYPE_BASIC ||
> -        type_get_type(var->type) == TYPE_ENUM)
> +    if (type_get_type(var->declspec.type) == TYPE_BASIC ||
> +        type_get_type(var->declspec.type) == TYPE_ENUM)
>       {
>           unsigned char fc;
>   
> @@ -1208,13 +1208,13 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
>           else
>               print_file(file, indent, "0x4e,    /* FC_IN_PARAM_BASETYPE */\n");
>   
> -        if (type_get_type(var->type) == TYPE_ENUM)
> +        if (type_get_type(var->declspec.type) == TYPE_ENUM)
>           {
> -            fc = get_enum_fc(var->type);
> +            fc = get_enum_fc(var->declspec.type);
>           }
>           else
>           {
> -            fc = get_basic_fc_signed(var->type);
> +            fc = get_basic_fc_signed(var->declspec.type);
>   
>               if (fc == FC_BIND_PRIMITIVE)
>                   fc = FC_IGNORE;
> @@ -1228,10 +1228,10 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons
>       {
>           unsigned short offset = var->typestring_offset;
>   
> -        if (!is_interpreted && is_array(var->type) &&
> -            type_array_is_decl_as_ptr(var->type) &&
> -            var->type->details.array.ptr_tfsoff)
> -            offset = var->type->typestring_offset;
> +        if (!is_interpreted && is_array(var->declspec.type) &&
> +            type_array_is_decl_as_ptr(var->declspec.type) &&
> +            var->declspec.type->details.array.ptr_tfsoff)
> +            offset = var->declspec.type->typestring_offset;
>   
>           if (is_return)
>               print_file(file, indent, "0x52,    /* FC_RETURN_PARAM */\n");
> @@ -1254,8 +1254,8 @@ 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->type );
> -    const type_t *ret_type = type_function_get_rettype( func->type );
> +    const var_list_t *args = type_get_function_args( func->declspec.type );
> +    const type_t *ret_type = type_function_get_rettype( func->declspec.type );
>   
>       if (type_get_type( ret_type ) == TYPE_BASIC)
>       {
> @@ -1277,10 +1277,10 @@ int is_interpreted_func( const type_t *iface, const var_t *func )
>       if (get_stub_mode() != MODE_Oif && args)
>       {
>           LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
> -            switch (type_get_type( var->type ))
> +            switch (type_get_type( var->declspec.type ))
>               {
>               case TYPE_BASIC:
> -                switch (type_basic_get_type( var->type ))
> +                switch (type_basic_get_type( var->declspec.type ))
>                   {
>                   /* floating point arguments are not supported in Oi mode */
>                   case TYPE_BASIC_FLOAT:  return 0;
> @@ -1305,7 +1305,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->type );
> +    var_list_t *args = type_get_function_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 );
> @@ -1336,7 +1336,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
>           param_num++;
>           nb_args++;
>       }
> -    if (!is_void( type_function_get_rettype( func->type )))
> +    if (!is_void( type_function_get_rettype( func->declspec.type )))
>       {
>           stack_size += pointer_size;
>           nb_args++;
> @@ -1364,22 +1364,22 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
>               *offset += 4;
>               break;
>           case FC_BIND_GENERIC:
> -            handle_flags = type_memsize( handle_var->type );
> +            handle_flags = type_memsize( handle_var->declspec.type );
>               print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
>               print_file( file, indent, "0x%02x,\n", handle_flags );
>               print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
>                           handle_stack_offset, handle_stack_offset );
> -            print_file( file, indent, "0x%02x,\n", get_generic_handle_offset( handle_var->type ) );
> +            print_file( file, indent, "0x%02x,\n", get_generic_handle_offset( handle_var->declspec.type ) );
>               print_file( file, indent, "0x%x,\t/* FC_PAD */\n", FC_PAD);
>               *offset += 6;
>               break;
>           case FC_BIND_CONTEXT:
> -            handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->type, 0 );
> +            handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->declspec.type, 0 );
>               print_file( file, indent, "0x%02x,\t/* %s */\n", explicit_fc, string_of_type(explicit_fc) );
>               print_file( file, indent, "0x%02x,\n", handle_flags );
>               print_file( file, indent, "NdrFcShort(0x%hx),\t/* stack offset = %hu */\n",
>                           handle_stack_offset, handle_stack_offset );
> -            print_file( file, indent, "0x%02x,\n", get_context_handle_offset( handle_var->type ) );
> +            print_file( file, indent, "0x%02x,\n", get_context_handle_offset( handle_var->declspec.type ) );
>               print_file( file, indent, "0x%02x,\t/* param %hu */\n", handle_param_num, handle_param_num );
>               *offset += 6;
>               break;
> @@ -1415,9 +1415,9 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
>               if (is_object( iface )) pos += 2;
>               if (args) LIST_FOR_EACH_ENTRY( var, args, var_t, entry )
>               {
> -                if (type_get_type( var->type ) == TYPE_BASIC)
> +                if (type_get_type( var->declspec.type ) == TYPE_BASIC)
>                   {
> -                    switch (type_basic_get_type( var->type ))
> +                    switch (type_basic_get_type( var->declspec.type ))
>                       {
>                       case TYPE_BASIC_FLOAT:  fpu_mask |= 1 << pos; break;
>                       case TYPE_BASIC_DOUBLE: fpu_mask |= 2 << pos; break;
> @@ -1440,15 +1440,15 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
>       unsigned int stack_offset = is_object( iface ) ? pointer_size : 0;
>       int is_interpreted = is_interpreted_func( iface, func );
>       int is_new_style = is_interpreted && (get_stub_mode() == MODE_Oif);
> -    var_t *retval = type_function_get_retval( func->type );
> +    var_t *retval = type_function_get_retval( func->declspec.type );
>   
>       if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc );
>   
>       /* emit argument data */
> -    if (type_get_function_args(func->type))
> +    if (type_get_function_args(func->declspec.type))
>       {
>           const var_t *var;
> -        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> +        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
>           {
>               print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
>               if (is_new_style)
> @@ -1459,7 +1459,7 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
>       }
>   
>       /* emit return value data */
> -    if (is_void(retval->type))
> +    if (is_void(retval->declspec.type))
>       {
>           if (!is_new_style)
>           {
> @@ -1606,7 +1606,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
>       {
>           conftype = FC_TOP_LEVEL_CONFORMANCE;
>           conftype_string = "parameter";
> -        cont_type = current_func->type;
> +        cont_type = current_func->declspec.type;
>           name = current_func->name;
>           iface = current_iface;
>       }
> @@ -1677,7 +1677,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
>                   if (var->name && !strcmp(var->name, subexpr->u.sval))
>                   {
>                       expr_loc.v = var;
> -                    correlation_variable = var->type;
> +                    correlation_variable = var->declspec.type;
>                       break;
>                   }
>                   offset += get_stack_size( var, NULL );
> @@ -1689,11 +1689,11 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
>   
>               if (fields) LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
>               {
> -                unsigned int size = field_memsize( var->type, &offset );
> +                unsigned int size = field_memsize( var->declspec.type, &offset );
>                   if (var->name && !strcmp(var->name, subexpr->u.sval))
>                   {
>                       expr_loc.v = var;
> -                    correlation_variable = var->type;
> +                    correlation_variable = var->declspec.type;
>                       break;
>                   }
>                   offset += size;
> @@ -1832,7 +1832,7 @@ static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align
>       LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
>       {
>           unsigned int falign = 0;
> -        unsigned int fsize = type_memsize_and_alignment(v->type, &falign);
> +        unsigned int fsize = type_memsize_and_alignment(v->declspec.type, &falign);
>           if (*align < falign) *align = falign;
>           falign = clamp_align(falign);
>           size = ROUND_SIZE(size, falign);
> @@ -1854,9 +1854,9 @@ static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa)
>       if (fields) LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
>       {
>           /* we could have an empty default field with NULL type */
> -        if (v->type)
> +        if (v->declspec.type)
>           {
> -            size = type_memsize_and_alignment(v->type, &align);
> +            size = type_memsize_and_alignment(v->declspec.type, &align);
>               if (maxs < size) maxs = size;
>               if (*pmaxa < align) *pmaxa = align;
>           }
> @@ -2029,8 +2029,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
>           if (!(fields = type_struct_get_fields(t))) break;
>           LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
>           {
> -            if (!var->type) continue;
> -            align = type_buffer_alignment( var->type );
> +            if (!var->declspec.type) continue;
> +            align = type_buffer_alignment( var->declspec.type );
>               if (max < align) max = align;
>           }
>           break;
> @@ -2038,8 +2038,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
>           if (!(fields = type_encapsulated_union_get_fields(t))) break;
>           LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
>           {
> -            if (!var->type) continue;
> -            align = type_buffer_alignment( var->type );
> +            if (!var->declspec.type) continue;
> +            align = type_buffer_alignment( var->declspec.type );
>               if (max < align) max = align;
>           }
>           break;
> @@ -2047,8 +2047,8 @@ static unsigned int type_buffer_alignment(const type_t *t)
>           if (!(fields = type_union_get_cases(t))) break;
>           LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
>           {
> -            if (!var->type) continue;
> -            align = type_buffer_alignment( var->type );
> +            if (!var->declspec.type) continue;
> +            align = type_buffer_alignment( var->declspec.type );
>               if (max < align) max = align;
>           }
>           break;
> @@ -2077,12 +2077,12 @@ static unsigned int type_buffer_alignment(const type_t *t)
>   int is_full_pointer_function(const var_t *func)
>   {
>       const var_t *var;
> -    if (type_has_full_pointer(type_function_get_rettype(func->type), func->attrs, TRUE))
> +    if (type_has_full_pointer(type_function_get_rettype(func->declspec.type), func->attrs, TRUE))
>           return TRUE;
> -    if (!type_get_function_args(func->type))
> +    if (!type_get_function_args(func->declspec.type))
>           return FALSE;
> -    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> -        if (type_has_full_pointer( var->type, var->attrs, TRUE ))
> +    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
> +        if (type_has_full_pointer( var->declspec.type, var->attrs, TRUE ))
>               return TRUE;
>       return FALSE;
>   }
> @@ -2424,7 +2424,7 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
>   
>       if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry)
>       {
> -        type_t *ft = f->type;
> +        type_t *ft = f->declspec.type;
>           unsigned int size = field_memsize( ft, &offset );
>           if (type_get_type(ft) == TYPE_UNION && is_attr(f->attrs, ATTR_SWITCHIS))
>           {
> @@ -2519,13 +2519,13 @@ static int write_pointer_description_offsets(
>               {
>                   unsigned int padding;
>                   unsigned int align = 0;
> -                type_memsize_and_alignment(v->type, &align);
> +                type_memsize_and_alignment(v->declspec.type, &align);
>                   padding = ROUNDING(*offset_in_memory, align);
>                   *offset_in_memory += padding;
>                   *offset_in_buffer += padding;
>               }
>               written += write_pointer_description_offsets(
> -                file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
> +                file, v->attrs, v->declspec.type, offset_in_memory, offset_in_buffer,
>                   typestring_offset);
>           }
>       }
> @@ -2571,13 +2571,13 @@ static int write_no_repeat_pointer_descriptions(
>               {
>                   unsigned int padding;
>                   unsigned int align = 0;
> -                type_memsize_and_alignment(v->type, &align);
> +                type_memsize_and_alignment(v->declspec.type, &align);
>                   padding = ROUNDING(*offset_in_memory, align);
>                   *offset_in_memory += padding;
>                   *offset_in_buffer += padding;
>               }
>               written += write_no_repeat_pointer_descriptions(
> -                file, v->attrs, v->type,
> +                file, v->attrs, v->declspec.type,
>                   offset_in_memory, offset_in_buffer, typestring_offset);
>           }
>       }
> @@ -2640,13 +2640,13 @@ static int write_fixed_array_pointer_descriptions(
>               {
>                   unsigned int padding;
>                   unsigned int align = 0;
> -                type_memsize_and_alignment(v->type, &align);
> +                type_memsize_and_alignment(v->declspec.type, &align);
>                   padding = ROUNDING(*offset_in_memory, align);
>                   *offset_in_memory += padding;
>                   *offset_in_buffer += padding;
>               }
>               pointer_count += write_fixed_array_pointer_descriptions(
> -                file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
> +                file, v->attrs, v->declspec.type, offset_in_memory, offset_in_buffer,
>                   typestring_offset);
>           }
>       }
> @@ -2755,20 +2755,20 @@ static int write_varying_array_pointer_descriptions(
>               {
>                   unsigned int align = 0, padding;
>   
> -                if (is_array(v->type) && type_array_has_variance(v->type))
> +                if (is_array(v->declspec.type) && type_array_has_variance(v->declspec.type))
>                   {
>                       *offset_in_buffer = ROUND_SIZE(*offset_in_buffer, 4);
>                       /* skip over variance and offset in buffer */
>                       *offset_in_buffer += 8;
>                   }
>   
> -                type_memsize_and_alignment(v->type, &align);
> +                type_memsize_and_alignment(v->declspec.type, &align);
>                   padding = ROUNDING(*offset_in_memory, align);
>                   *offset_in_memory += padding;
>                   *offset_in_buffer += padding;
>               }
>               pointer_count += write_varying_array_pointer_descriptions(
> -                file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
> +                file, v->attrs, v->declspec.type, offset_in_memory, offset_in_buffer,
>                   typestring_offset);
>           }
>       }
> @@ -2820,7 +2820,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
>       else if (type_get_type(type) == TYPE_STRUCT &&
>                get_struct_fc(type) == FC_CPSTRUCT)
>       {
> -        type_t *carray = find_array_or_string_in_struct(type)->type;
> +        type_t *carray = find_array_or_string_in_struct(type)->declspec.type;
>           write_conformant_array_pointer_descriptions( file, NULL, carray,
>                                                        type_memsize(type), typestring_offset);
>       }
> @@ -3058,7 +3058,7 @@ static const var_t *find_array_or_string_in_struct(const type_t *type)
>           return NULL;
>   
>       last_field = LIST_ENTRY( list_tail(fields), const var_t, entry );
> -    ft = last_field->type;
> +    ft = last_field->declspec.type;
>   
>       if (is_conformant_array(ft) && !type_array_is_decl_as_ptr(ft))
>           return last_field;
> @@ -3081,7 +3081,7 @@ static void write_struct_members(FILE *file, const type_t *type,
>   
>       if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
>       {
> -        type_t *ft = field->type;
> +        type_t *ft = field->declspec.type;
>           unsigned int align = 0;
>           unsigned int size = type_memsize_and_alignment(ft, &align);
>           align = clamp_align(align);
> @@ -3110,7 +3110,7 @@ static void write_struct_members(FILE *file, const type_t *type,
>                   offset = ROUND_SIZE(offset, align);
>                   *typestring_offset += 1;
>               }
> -            write_member_type(file, type, is_complex, field->attrs, field->type, corroff,
> +            write_member_type(file, type, is_complex, field->attrs, field->declspec.type, corroff,
>                                 typestring_offset);
>               offset += size;
>           }
> @@ -3153,15 +3153,15 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
>                 name, USHRT_MAX, total_size - USHRT_MAX);
>   
>       if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
> -        write_embedded_types(file, f->attrs, f->type, f->name, FALSE, tfsoff);
> +        write_embedded_types(file, f->attrs, f->declspec.type, f->name, FALSE, tfsoff);
>   
>       array = find_array_or_string_in_struct(type);
> -    if (array && !processed(array->type))
> +    if (array && !processed(array->declspec.type))
>       {
> -        if(is_string_type(array->attrs, array->type))
> -            write_string_tfs(file, array->attrs, array->type, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
> +        if(is_string_type(array->attrs, array->declspec.type))
> +            write_string_tfs(file, array->attrs, array->declspec.type, TYPE_CONTEXT_CONTAINER, array->name, tfsoff);
>           else
> -            write_array_tfs(file, array->attrs, array->type, array->name, tfsoff);
> +            write_array_tfs(file, array->attrs, array->declspec.type, array->name, tfsoff);
>       }
>   
>       corroff = *tfsoff;
> @@ -3177,7 +3177,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
>   
>       if (array)
>       {
> -        unsigned int absoff = array->type->typestring_offset;
> +        unsigned int absoff = array->declspec.type->typestring_offset;
>           short reloff = absoff - *tfsoff;
>           print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
>                      reloff, reloff, absoff);
> @@ -3223,7 +3223,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
>           type->ptrdesc = *tfsoff;
>           if (fields) LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry)
>           {
> -            type_t *ft = f->type;
> +            type_t *ft = f->declspec.type;
>               switch (typegen_detect_type(ft, f->attrs, TDT_IGNORE_STRINGS))
>               {
>               case TGT_POINTER:
> @@ -3319,8 +3319,8 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
>           expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
>           if (cases)
>               nbranch += list_count(cases);
> -        if (f->type)
> -            write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff);
> +        if (f->declspec.type)
> +            write_embedded_types(file, f->attrs, f->declspec.type, f->name, TRUE, tfsoff);
>       }
>   
>       start_offset = *tfsoff;
> @@ -3329,7 +3329,7 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
>       if (type_get_type(type) == TYPE_ENCAPSULATED_UNION)
>       {
>           const var_t *sv = type_union_get_switch_value(type);
> -        const type_t *st = sv->type;
> +        const type_t *st = sv->declspec.type;
>           unsigned int align = 0;
>           unsigned char fc;
>   
> @@ -3361,8 +3361,8 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
>           type_memsize_and_alignment(st, &align);
>           if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
>           {
> -            if (f->type)
> -                type_memsize_and_alignment(f->type, &align);
> +            if (f->declspec.type)
> +                type_memsize_and_alignment(f->declspec.type, &align);
>           }
>   
>           print_file(file, 2, "0x%x,\t/* FC_ENCAPSULATED_UNION */\n", FC_ENCAPSULATED_UNION);
> @@ -3417,7 +3417,7 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
>   
>       if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
>       {
> -        type_t *ft = f->type;
> +        type_t *ft = f->declspec.type;
>           expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
>           int deflt = is_attr(f->attrs, ATTR_DEFAULT);
>           expr_t *c;
> @@ -3699,21 +3699,21 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
>           {
>               const var_t *func = stmt->u.var;
>   
> -            if(stmt->u.var->stgclass != STG_NONE
> -               || type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
> +            if(stmt->u.var->declspec.stgclass != STG_NONE
> +               || type_get_type_detect_alias(stmt->u.var->declspec.type) != TYPE_FUNCTION)
>                   continue;
>   
>               current_func = func;
>               if (is_local(func->attrs)) continue;
>   
> -            var = type_function_get_retval(func->type);
> -            if (!is_void(var->type))
> -                var->typestring_offset = write_type_tfs( file, var->attrs, var->type, func->name,
> +            var = type_function_get_retval(func->declspec.type);
> +            if (!is_void(var->declspec.type))
> +                var->typestring_offset = write_type_tfs( file, var->attrs, var->declspec.type, func->name,
>                                                            TYPE_CONTEXT_RETVAL, offset);
>   
> -            if (type_get_function_args(func->type))
> -                LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), var_t, entry )
> -                    var->typestring_offset = write_type_tfs( file, var->attrs, var->type, var->name,
> +            if (type_get_function_args(func->declspec.type))
> +                LIST_FOR_EACH_ENTRY( var, type_get_function_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;
>   
> @@ -3899,8 +3899,8 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
>               return 20;
>           }
>   
> -        if (!is_string_type(var->attrs, var->type))
> -            return get_required_buffer_size_type(var->type, var->name,
> +        if (!is_string_type(var->attrs, var->declspec.type))
> +            return get_required_buffer_size_type(var->declspec.type, var->name,
>                                                    var->attrs, TRUE, alignment);
>       }
>       return 0;
> @@ -3911,19 +3911,19 @@ 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->type))
> +    if (type_get_function_args(func->declspec.type))
>       {
> -        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> +        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
>           {
>               total_size += get_required_buffer_size(var, &alignment, pass);
>               total_size += alignment;
>           }
>       }
>   
> -    if (pass == PASS_OUT && !is_void(type_function_get_rettype(func->type)))
> +    if (pass == PASS_OUT && !is_void(type_function_get_rettype(func->declspec.type)))
>       {
>           var_t v = *func;
> -        v.type = type_function_get_rettype(func->type);
> +        v.declspec.type = type_function_get_rettype(func->declspec.type);
>           total_size += get_required_buffer_size(&v, &alignment, PASS_RETURN);
>           total_size += alignment;
>       }
> @@ -3959,9 +3959,9 @@ static void print_phase_function(FILE *file, int indent, const char *type,
>       print_file(file, indent, "&__frame->_StubMsg,\n");
>       print_file(file, indent, "%s%s%s%s%s,\n",
>                  (phase == PHASE_UNMARSHAL) ? "(unsigned char **)" : "(unsigned char *)",
> -               (phase == PHASE_UNMARSHAL || decl_indirect(var->type)) ? "&" : "",
> +               (phase == PHASE_UNMARSHAL || decl_indirect(var->declspec.type)) ? "&" : "",
>                  local_var_prefix,
> -               (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "",
> +               (phase == PHASE_UNMARSHAL && decl_indirect(var->declspec.type)) ? "_p_" : "",
>                  var->name);
>       print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n",
>                  type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");");
> @@ -3974,7 +3974,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
>                             enum remoting_phase phase, enum pass pass, const var_t *var,
>                             const char *varname)
>   {
> -    type_t *type = var->type;
> +    type_t *type = var->declspec.type;
>       unsigned int alignment = 0;
>   
>       /* no work to do for other phases, buffer sizing is done elsewhere */
> @@ -4116,7 +4116,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
>   void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local_var_prefix,
>                                          enum remoting_phase phase, const var_t *var, int valid_variance)
>   {
> -    const type_t *type = var->type;
> +    const type_t *type = var->declspec.type;
>       /* get fundamental type for the argument */
>       for (;;)
>       {
> @@ -4190,7 +4190,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
>   {
>       int in_attr, out_attr, pointer_type;
>       const char *type_str = NULL;
> -    const type_t *type = var->type;
> +    const type_t *type = var->declspec.type;
>       unsigned int alignment, start_offset = type->typestring_offset;
>   
>       if (is_ptr(type) || is_array(type))
> @@ -4243,7 +4243,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
>                   print_file(file, indent, "NdrServerContextNewMarshall(\n");
>                   print_file(file, indent + 1, "&__frame->_StubMsg,\n");
>                   print_file(file, indent + 1, "(NDR_SCONTEXT)%s%s,\n", local_var_prefix, var->name);
> -                print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown,\n", get_context_handle_type_name(var->type));
> +                print_file(file, indent + 1, "(NDR_RUNDOWN)%s_rundown,\n", get_context_handle_type_name(var->declspec.type));
>                   print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset);
>               }
>           }
> @@ -4387,9 +4387,9 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
>               range_max = LIST_ENTRY(list_next(range_list, list_head(range_list)), const expr_t, entry);
>   
>               print_file(file, indent, "if ((%s%s < (", local_var_prefix, var->name);
> -            write_type_decl(file, var->type, NULL);
> +            write_type_decl(file, var->declspec.type, NULL);
>               fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
> -            write_type_decl(file, var->type, NULL);
> +            write_type_decl(file, var->declspec.type, NULL);
>               fprintf(file, ")0x%x))\n", range_max->cval);
>               print_file(file, indent, "{\n");
>               print_file(file, indent+1, "RpcRaiseException(RPC_S_INVALID_BOUND);\n");
> @@ -4556,14 +4556,14 @@ void write_remoting_arguments(FILE *file, int indent, const var_t *func, const c
>       if (pass == PASS_RETURN)
>       {
>           write_remoting_arg( file, indent, func, local_var_prefix, pass, phase,
> -                            type_function_get_retval(func->type) );
> +                            type_function_get_retval(func->declspec.type) );
>       }
>       else
>       {
>           const var_t *var;
> -        if (!type_get_function_args(func->type))
> +        if (!type_get_function_args(func->declspec.type))
>               return;
> -        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> +        LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
>               write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var );
>       }
>   }
> @@ -4604,62 +4604,62 @@ void declare_stub_args( FILE *file, int indent, const var_t *func )
>   {
>       int in_attr, out_attr;
>       int i = 0;
> -    const var_t *var = type_function_get_retval(func->type);
> +    const var_t *var = type_function_get_retval(func->declspec.type);
>   
>       /* declare return value */
> -    if (!is_void(var->type))
> +    if (!is_void(var->declspec.type))
>       {
> -        if (is_context_handle(var->type))
> +        if (is_context_handle(var->declspec.type))
>               print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
>           else
>           {
>               print_file(file, indent, "%s", "");
> -            write_type_decl(file, var->type, var->name);
> +            write_type_decl(file, var->declspec.type, var->name);
>               fprintf(file, ";\n");
>           }
>       }
>   
> -    if (!type_get_function_args(func->type))
> +    if (!type_get_function_args(func->declspec.type))
>           return;
>   
> -    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> +    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
>       {
>           in_attr = is_attr(var->attrs, ATTR_IN);
>           out_attr = is_attr(var->attrs, ATTR_OUT);
>           if (!out_attr && !in_attr)
>               in_attr = 1;
>   
> -        if (is_context_handle(var->type))
> +        if (is_context_handle(var->declspec.type))
>               print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
>           else
>           {
> -            if (!in_attr && !is_conformant_array(var->type))
> +            if (!in_attr && !is_conformant_array(var->declspec.type))
>               {
>                   type_t *type_to_print;
>                   char name[16];
>                   print_file(file, indent, "%s", "");
> -                if (type_get_type(var->type) == TYPE_ARRAY &&
> -                    !type_array_is_decl_as_ptr(var->type))
> -                    type_to_print = var->type;
> +                if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
> +                    !type_array_is_decl_as_ptr(var->declspec.type))
> +                    type_to_print = var->declspec.type;
>                   else
> -                    type_to_print = type_pointer_get_ref(var->type);
> +                    type_to_print = type_pointer_get_ref(var->declspec.type);
>                   sprintf(name, "_W%u", i++);
>                   write_type_decl(file, type_to_print, name);
>                   fprintf(file, ";\n");
>               }
>   
>               print_file(file, indent, "%s", "");
> -            write_type_decl_left(file, var->type);
> +            write_type_decl_left(file, var->declspec.type);
>               fprintf(file, " ");
> -            if (type_get_type(var->type) == TYPE_ARRAY &&
> -                !type_array_is_decl_as_ptr(var->type)) {
> +            if (type_get_type(var->declspec.type) == TYPE_ARRAY &&
> +                !type_array_is_decl_as_ptr(var->declspec.type)) {
>                   fprintf(file, "(*%s)", var->name);
>               } else
>                   fprintf(file, "%s", var->name);
> -            write_type_right(file, var->type, FALSE);
> +            write_type_right(file, var->declspec.type, FALSE);
>               fprintf(file, ";\n");
>   
> -            if (decl_indirect(var->type))
> +            if (decl_indirect(var->declspec.type))
>                   print_file(file, indent, "void *_p_%s;\n", var->name);
>           }
>       }
> @@ -4673,10 +4673,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->type))
> +    if (!type_get_function_args(func->declspec.type))
>           return;
>   
> -    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry )
> +    LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->declspec.type), const var_t, entry )
>       {
>           in_attr = is_attr(var->attrs, ATTR_IN);
>           out_attr = is_attr(var->attrs, ATTR_OUT);
> @@ -4687,7 +4687,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
>           {
>               print_file(file, indent, "%s%s", local_var_prefix, var->name);
>   
> -            switch (typegen_detect_type(var->type, var->attrs, TDT_IGNORE_STRINGS))
> +            switch (typegen_detect_type(var->declspec.type, var->attrs, TDT_IGNORE_STRINGS))
>               {
>               case TGT_CTXT_HANDLE_POINTER:
>                   fprintf(file, " = NdrContextHandleInitialize(\n");
> @@ -4696,13 +4696,13 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
>                              var->typestring_offset);
>                   break;
>               case TGT_ARRAY:
> -                if (type_array_has_conformance(var->type))
> +                if (type_array_has_conformance(var->declspec.type))
>                   {
>                       unsigned int size;
>                       type_t *type;
>   
>                       fprintf(file, " = NdrAllocate(&__frame->_StubMsg, ");
> -                    for (type = var->type;
> +                    for (type = var->declspec.type;
>                            is_array(type) && type_array_has_conformance(type);
>                            type = type_array_get_element(type))
>                       {
> @@ -4714,7 +4714,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
>                       fprintf(file, "%u);\n", size);
>   
>                       print_file(file, indent, "memset(%s%s, 0, ", local_var_prefix, var->name);
> -                    for (type = var->type;
> +                    for (type = var->declspec.type;
>                            is_array(type) && type_array_has_conformance(type);
>                            type = type_array_get_element(type))
>                       {
> @@ -4730,7 +4730,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
>                   break;
>               case TGT_POINTER:
>                   fprintf(file, " = &%s_W%u;\n", local_var_prefix, i);
> -                ref = type_pointer_get_ref(var->type);
> +                ref = type_pointer_get_ref(var->declspec.type);
>                   switch (typegen_detect_type(ref, var->attrs, TDT_IGNORE_STRINGS))
>                   {
>                   case TGT_BASIC:
> @@ -4790,7 +4790,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
>   
>       if (args)
>           LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
> -            if (!is_array( arg->type )) type_memsize_and_alignment( arg->type, &align );
> +            if (!is_array( arg->declspec.type )) type_memsize_and_alignment( arg->declspec.type, &align );
>   
>       needs_packing = (align > pointer_size);
>   
> @@ -4802,26 +4802,26 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
>       if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
>       {
>           print_file(file, 2, "%s", "");
> -        write_type_left( file, (type_t *)arg->type, NAME_DEFAULT, TRUE );
> -        if (needs_space_after( arg->type )) fputc( ' ', file );
> -        if (is_array( arg->type ) && !type_array_is_decl_as_ptr( arg->type )) fputc( '*', file );
> +        write_type_left( file, (type_t *)arg->declspec.type, NAME_DEFAULT, TRUE );
> +        if (needs_space_after( arg->declspec.type )) fputc( ' ', file );
> +        if (is_array( arg->declspec.type ) && !type_array_is_decl_as_ptr( arg->declspec.type )) fputc( '*', file );
>   
>           /* FIXME: should check for large args being passed by pointer */
>           align = 0;
> -        if (is_array( arg->type ) || is_ptr( arg->type )) align = pointer_size;
> -        else type_memsize_and_alignment( arg->type, &align );
> +        if (is_array( arg->declspec.type ) || is_ptr( arg->declspec.type )) align = pointer_size;
> +        else type_memsize_and_alignment( arg->declspec.type, &align );
>   
>           if (align >= pointer_size)
>               fprintf( file, "%s;\n", arg->name );
>           else
>               fprintf( file, "%s DECLSPEC_ALIGN(%u);\n", arg->name, pointer_size );
>       }
> -    if (add_retval && !is_void( retval->type ))
> +    if (add_retval && !is_void( retval->declspec.type ))
>       {
>           print_file(file, 2, "%s", "");
> -        write_type_decl( file, retval->type, retval->name );
> -        if (is_array( retval->type ) || is_ptr( retval->type ) ||
> -            type_memsize( retval->type ) == pointer_size)
> +        write_type_decl( file, retval->declspec.type, retval->name );
> +        if (is_array( retval->declspec.type ) || is_ptr( retval->declspec.type ) ||
> +            type_memsize( retval->declspec.type ) == pointer_size)
>               fprintf( file, ";\n" );
>           else
>               fprintf( file, " DECLSPEC_ALIGN(%u);\n", pointer_size );
> @@ -4833,7 +4833,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->type );
> +    const var_list_t *args = type_get_function_args( func->declspec.type );
>       const var_t *var;
>   
>       if (!args) return;
> @@ -4963,9 +4963,9 @@ error:
>   void write_client_call_routine( FILE *file, const type_t *iface, const var_t *func,
>                                   const char *prefix, unsigned int proc_offset )
>   {
> -    type_t *rettype = type_function_get_rettype( func->type );
> +    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->type );
> +    const var_list_t *args = type_get_function_args( func->declspec.type );
>       const var_t *arg;
>       int len, needs_params = 0;
>   
> @@ -4976,7 +4976,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
>       if (needs_params)
>       {
>           if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n" );
> -        write_func_param_struct( file, iface, func->type, "__params", FALSE );
> +        write_func_param_struct( file, iface, func->declspec.type, "__params", FALSE );
>           if (is_object( iface )) print_file( file, 1, "__params.This = This;\n" );
>           if (args)
>               LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
> diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
> index b93806be98..3b0c944387 100644
> --- a/tools/widl/typetree.c
> +++ b/tools/widl/typetree.c
> @@ -137,7 +137,7 @@ type_t *type_new_function(var_list_t *args)
>       if (args)
>       {
>           arg = LIST_ENTRY(list_head(args), var_t, entry);
> -        if (list_count(args) == 1 && !arg->name && arg->type && type_get_type(arg->type) == TYPE_VOID)
> +        if (list_count(args) == 1 && !arg->name && arg->declspec.type && type_get_type(arg->declspec.type) == TYPE_VOID)
>           {
>               list_remove(&arg->entry);
>               free(arg);
> @@ -147,7 +147,7 @@ type_t *type_new_function(var_list_t *args)
>       }
>       if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
>       {
> -        if (arg->type && type_get_type(arg->type) == TYPE_VOID)
> +        if (arg->declspec.type && type_get_type(arg->declspec.type) == TYPE_VOID)
>               error_loc("argument '%s' has void type\n", arg->name);
>           if (!arg->name)
>           {
> @@ -354,7 +354,7 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio
>   {
>       type_t *t = get_type(TYPE_ENCAPSULATED_UNION, name, NULL, tsUNION);
>       if (!union_field) union_field = make_var( xstrdup("tagged_union") );
> -    union_field->type = type_new_nonencapsulated_union(NULL, TRUE, cases);
> +    union_field->declspec.type = type_new_nonencapsulated_union(NULL, TRUE, cases);
>       t->details.structure = xmalloc(sizeof(*t->details.structure));
>       t->details.structure->fields = append_var( NULL, switch_field );
>       t->details.structure->fields = append_var( t->details.structure->fields, union_field );
> @@ -430,7 +430,7 @@ static int compute_method_indexes(type_t *iface)
>       {
>           var_t *func = stmt->u.var;
>           if (!is_callas(func->attrs))
> -            func->type->details.function->idx = idx++;
> +            func->declspec.type->details.function->idx = idx++;
>       }
>   
>       return idx;
> diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
> index fc134cd575..9f0dc5afc6 100644
> --- a/tools/widl/typetree.h
> +++ b/tools/widl/typetree.h
> @@ -107,7 +107,7 @@ static inline var_t *type_function_get_retval(const type_t *type)
>   
>   static inline type_t *type_function_get_rettype(const type_t *type)
>   {
> -    return type_function_get_retval(type)->type;
> +    return type_function_get_retval(type)->declspec.type;
>   }
>   
>   static inline var_list_t *type_enum_get_values(const type_t *type)
> @@ -142,7 +142,7 @@ static inline var_list_t *type_union_get_cases(const type_t *type)
>       if (type_type == TYPE_ENCAPSULATED_UNION)
>       {
>           const var_t *uv = LIST_ENTRY(list_tail(type->details.structure->fields), const var_t, entry);
> -        return uv->type->details.structure->fields;
> +        return uv->declspec.type->details.structure->fields;
>       }
>       else
>           return type->details.structure->fields;
> diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
> index 1177c1a00a..31a0cc74dd 100644
> --- a/tools/widl/widltypes.h
> +++ b/tools/widl/widltypes.h
> @@ -40,6 +40,7 @@ typedef struct _attr_t attr_t;
>   typedef struct _expr_t expr_t;
>   typedef struct _type_t type_t;
>   typedef struct _var_t var_t;
> +typedef struct _decl_spec_t decl_spec_t;
>   typedef struct _declarator_t declarator_t;
>   typedef struct _ifref_t ifref_t;
>   typedef struct _typelib_entry_t typelib_entry_t;
> @@ -293,6 +294,13 @@ struct str_list_entry_t
>       struct list entry;
>   };
>   
> +struct _decl_spec_t
> +{
> +  type_t *type;
> +  attr_list_t *attrs;
> +  enum storage_class stgclass;
> +};
> +
>   struct _attr_t {
>     enum attr_type type;
>     union {
> @@ -449,10 +457,10 @@ struct _type_t {
>   
>   struct _var_t {
>     char *name;
> -  type_t *type;
> +  decl_spec_t declspec;
> +
>     attr_list_t *attrs;
>     expr_t *eval;
> -  enum storage_class stgclass;
>     unsigned int procstring_offset;
>     unsigned int typestring_offset;
>   
> @@ -596,8 +604,8 @@ static inline enum type_type type_get_type_detect_alias(const type_t *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->stgclass == STG_NONE && \
> -        type_get_type_detect_alias(stmt->u.var->type) == TYPE_FUNCTION)
> +    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)
>   {
> @@ -616,4 +624,13 @@ static inline int is_global_namespace(const struct namespace *namespace)
>       return !namespace->name;
>   }
>   
> +static inline decl_spec_t *init_declspec(decl_spec_t *declspec, type_t *type)
> +{
> +  declspec->type = type;
> +  declspec->attrs = NULL;
> +  declspec->stgclass = STG_NONE;
> +
> +  return declspec;
> +}
> +
>   #endif
> diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c
> index 4dcbc03702..7738cae729 100644
> --- a/tools/widl/write_msft.c
> +++ b/tools/widl/write_msft.c
> @@ -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->type))
> -      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
> +    if (type_get_function_args(func->declspec.type))
> +      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), var_t, entry )
>         {
>           num_params++;
>           if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
> @@ -1444,7 +1444,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
>   
>       /* fill out the basic type information */
>       typedata[0] = typedata_size | (index << 16);
> -    encode_var(typeinfo->typelib, type_function_get_rettype(func->type), func,
> +    encode_var(typeinfo->typelib, type_function_get_rettype(func->declspec.type), func,
>           &typedata[1], &decoded_size);
>       typedata[2] = funcflags;
>       typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
> @@ -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->type))
> +    if (type_get_function_args(func->declspec.type))
>       {
>         i = 0;
> -      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
> +      LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->declspec.type), var_t, entry )
>         {
>           int paramflags = 0;
>           int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
> @@ -1482,13 +1482,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
>   
>           if(defaultdata) *defaultdata = -1;
>   
> -	encode_var(typeinfo->typelib, arg->type, arg, paramdata, &decoded_size);
> +	    encode_var(typeinfo->typelib, arg->declspec.type, arg, paramdata, &decoded_size);
>           if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
>               switch(attr->type) {
>               case ATTR_DEFAULTVALUE:
>                 {
>                   paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
> -                write_default_value(typeinfo->typelib, arg->type, (expr_t *)attr->u.pval, defaultdata);
> +                write_default_value(typeinfo->typelib, arg->declspec.type, (expr_t *)attr->u.pval, defaultdata);
>                   break;
>                 }
>               case ATTR_IN:
> @@ -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->type))
> +    if (type_get_function_args(func->declspec.type))
>       {
>           i = 0;
> -        LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry )
> +        LIST_FOR_EACH_ENTRY( arg, type_get_function_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 */))
> @@ -1697,8 +1697,8 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
>       typeinfo->var_offsets[var_num] = offset;
>   
>       /* figure out type widths and whatnot */
> -    var_datawidth = type_memsize_and_alignment(var->type, &var_alignment);
> -    encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_type_size);
> +    var_datawidth = type_memsize_and_alignment(var->declspec.type, &var_alignment);
> +    encode_var(typeinfo->typelib, var->declspec.type, var, &typedata[1], &var_type_size);
>   
>       /* pad out starting position to data width */
>       typeinfo->datawidth += var_alignment - 1;
> 




More information about the wine-devel mailing list