tbb-commits
Threads by month
- ----- 2025 -----
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 18541 discussions

[tor-browser-build/maint-8.5] Bug 27503: add patch for fixed widl to mingw and update build/config to apply it
by gkï¼ torproject.org 28 Aug '19
by gkï¼ torproject.org 28 Aug '19
28 Aug '19
commit 75a80131971499cff36930b3eba75306749a1e5c
Author: Richard Pospesel <richard(a)torproject.org>
Date: Thu Jun 6 18:08:48 2019 -0700
Bug 27503: add patch for fixed widl to mingw and update build/config to apply it
---
projects/mingw-w64/27503.patch | 10660 +++++++++++++++++++++++++++++++++++++++
projects/mingw-w64/build | 3 +
projects/mingw-w64/config | 1 +
3 files changed, 10664 insertions(+)
diff --git a/projects/mingw-w64/27503.patch b/projects/mingw-w64/27503.patch
new file mode 100644
index 0000000..f6bd197
--- /dev/null
+++ b/projects/mingw-w64/27503.patch
@@ -0,0 +1,10660 @@
+diff --git a/mingw-w64-tools/widl/src/client.c b/mingw-w64-tools/widl/src/client.c
+index a3b2bbb6..d27c6cad 100644
+--- a/mingw-w64-tools/widl/src/client.c
++++ b/mingw-w64-tools/widl/src/client.c
+@@ -20,7 +20,7 @@
+
+ #include "config.h"
+ #include "wine/port.h"
+-
++
+ #include <stdio.h>
+ #include <stdlib.h>
+ #ifdef HAVE_UNISTD_H
+@@ -34,7 +34,7 @@
+ #include "parser.h"
+ #include "header.h"
+
+-#include "widltypes.h"
++#include "typetree.h"
+ #include "typegen.h"
+ #include "expr.h"
+
+@@ -52,12 +52,13 @@ 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_function_get_args(func->declspec.type);
++ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
+
+ if (!callconv) callconv = "__cdecl";
+- write_type_decl_left(client, rettype);
++ write_declspec_decl_left(client, retdeclspec);
++ if (func->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(client, " inline");
+ fprintf(client, " %s ", callconv);
+ fprintf(client, "%s%s(\n", prefix_client, get_name(func));
+ indent++;
+@@ -74,9 +75,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 +98,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 +137,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_declspec_decl(client, &retval->declspec, retval->name);
+ fprintf(client, ";\n");
+ }
+ print_client("RPC_MESSAGE _RpcMessage;\n");
+@@ -147,7 +148,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 +195,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 +258,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);
+ }
+@@ -291,7 +292,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ const char *func_name, const char *ret_type)
+ {
+ enum stub_mode mode = get_stub_mode();
+- static int emited_pickling_info;
++ static int emitted_pickling_info;
+
+ if (iface && !type->typestring_offset)
+ {
+@@ -301,7 +302,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ return;
+ }
+
+- if (!emited_pickling_info && iface && mode != MODE_Os)
++ if (!emitted_pickling_info && iface && mode != MODE_Os)
+ {
+ fprintf(file, "static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =\n");
+ fprintf(file, "{\n");
+@@ -312,7 +313,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
+ fprintf(file, " 0\n");
+ fprintf(file, "};\n");
+ fprintf(file, "\n");
+- emited_pickling_info = 1;
++ emitted_pickling_info = 1;
+ }
+
+ /* FIXME: Assuming explicit handle */
+@@ -365,8 +366,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 );
+@@ -425,7 +426,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
+ print_client("1, /* -error bounds_check flag */\n");
+ print_client("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_client("0,\n");
+- print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_client("0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_client("0,\n");
+ print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_client("0, /* notify & notify_flag routine table */\n");
+@@ -488,7 +489,7 @@ static void write_implicithandledecl(type_t *iface)
+
+ if (implicit_handle)
+ {
+- write_type_decl( client, implicit_handle->type, implicit_handle->name );
++ write_declspec_decl( client, &implicit_handle->declspec, implicit_handle->name );
+ fprintf(client, ";\n\n");
+ }
+ }
+@@ -532,8 +533,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;
+@@ -627,26 +628,6 @@ void write_client(const statement_list_t *stmts)
+ if (!client)
+ return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(client, "#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_client_routines( stmts );
+- fprintf(client, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_client_routines( stmts );
+- fprintf(client, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_client_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_client_routines( stmts );
+- }
+-
++ write_client_routines( stmts );
+ fclose(client);
+ }
+diff --git a/mingw-w64-tools/widl/src/expr.c b/mingw-w64-tools/widl/src/expr.c
+index 2ed4aff6..2f075816 100644
+--- a/mingw-w64-tools/widl/src/expr.c
++++ b/mingw-w64-tools/widl/src/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;
+@@ -521,11 +521,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ break;
+ case EXPR_STRLIT:
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
++ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0));
+ break;
+ case EXPR_WSTRLIT:
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
++ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0));
+ break;
+ case EXPR_CHARCONST:
+ result.is_temporary = TRUE;
+@@ -575,15 +575,15 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ expr_loc->attr ? expr_loc->attr : "");
+ result.is_variable = FALSE;
+ result.is_temporary = TRUE;
+- result.type = type_new_pointer(FC_UP, result.type, NULL);
++ result.type = type_new_pointer(FC_UP, result.type);
+ break;
+ case EXPR_PPTR:
+ result = resolve_expression(expr_loc, cont_type, e->ref);
+ if (result.type && is_ptr(result.type))
+- result.type = type_pointer_get_ref(result.type);
++ result.type = type_pointer_get_ref_type(result.type);
+ else if(result.type && is_array(result.type)
+ && type_array_is_decl_as_ptr(result.type))
+- result.type = type_array_get_element(result.type);
++ result.type = type_array_get_element_type(result.type);
+ else
+ error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
+ expr_loc->attr ? " for attribute " : "",
+@@ -665,7 +665,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
+ if (result.type && is_array(result.type))
+ {
+ struct expression_type index_result;
+- result.type = type_array_get_element(result.type);
++ result.type = type_array_get_element_type(result.type);
+ index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
+ if (!index_result.type || !is_integer_type(index_result.type))
+ error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
+diff --git a/mingw-w64-tools/widl/src/header.c b/mingw-w64-tools/widl/src/header.c
+index defc7f85..d0d0dc4b 100644
+--- a/mingw-w64-tools/widl/src/header.c
++++ b/mingw-w64-tools/widl/src/header.c
+@@ -43,7 +43,7 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list);
+ context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
+ generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
+
+-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name);
++static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name);
+
+ static void indent(FILE *h, int delta)
+ {
+@@ -69,15 +69,15 @@ 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))
+ return 1;
+ else if (type_is_alias(type))
+- type = type_alias_get_aliasee(type);
++ type = type_alias_get_aliasee_type(type);
+ else if (is_ptr(type))
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ else return 0;
+ }
+ }
+@@ -91,7 +91,7 @@ int is_aliaschain_attr(const type_t *type, enum attr_type attr)
+ if (is_attr(t->attrs, attr))
+ return 1;
+ else if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else return 0;
+ }
+ }
+@@ -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_v(h, &v->declspec, TRUE, v->declonly, name);
+ fprintf(h, ";\n");
+ }
+ }
+@@ -295,14 +295,21 @@ static void write_pointer_left(FILE *h, type_t *ref)
+ }
+
+ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
++{
++ decl_spec_t ds;
++ write_declspec_left(h, init_declspec(&ds, t), name_type, declonly);
++}
++
++void write_declspec_left(FILE* h, const decl_spec_t *ds, enum name_type name_type, int declonly)
+ {
+ const char *name;
++ type_t *t = ds->type;
+
+ if (!h) return;
+
+ name = type_get_name(t, name_type);
+
+- if (is_attr(t->attrs, ATTR_CONST) &&
++ if ((ds->typequalifier == TYPE_QUALIFIER_CONST) &&
+ (type_is_alias(t) || !is_ptr(t)))
+ fprintf(h, "const ");
+
+@@ -310,7 +317,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ else {
+ switch (type_get_type_detect_alias(t)) {
+ case TYPE_ENUM:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (name) fprintf(h, "enum %s {\n", name);
+ else fprintf(h, "enum {\n");
+ t->written = TRUE;
+@@ -323,7 +330,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ break;
+ case TYPE_STRUCT:
+ case TYPE_ENCAPSULATED_UNION:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (name) fprintf(h, "struct %s {\n", name);
+ else fprintf(h, "struct {\n");
+ t->written = TRUE;
+@@ -338,7 +345,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ else fprintf(h, "struct %s", name ? name : "");
+ break;
+ case TYPE_UNION:
+- if (!declonly && t->defined && !t->written) {
++ if (!declonly && type_is_defined(t) && !t->written) {
+ if (t->name) fprintf(h, "union %s {\n", t->name);
+ else fprintf(h, "union {\n");
+ t->written = TRUE;
+@@ -351,9 +358,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ break;
+ case TYPE_POINTER:
+ {
+- write_type_left(h, type_pointer_get_ref(t), name_type, declonly);
+- write_pointer_left(h, type_pointer_get_ref(t));
+- if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
++ write_declspec_left(h, type_pointer_get_ref(t), name_type, declonly);
++ write_pointer_left(h, type_pointer_get_ref_type(t));
++ if (ds->typequalifier == TYPE_QUALIFIER_CONST) fprintf(h, "const ");
+ break;
+ }
+ case TYPE_ARRAY:
+@@ -361,9 +368,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
+ fprintf(h, "%s", t->name);
+ else
+ {
+- write_type_left(h, type_array_get_element(t), name_type, declonly);
++ write_declspec_left(h, type_array_get_element(t), name_type, declonly);
+ if (type_array_is_decl_as_ptr(t))
+- write_pointer_left(h, type_array_get_element(t));
++ write_pointer_left(h, type_array_get_element_type(t));
+ }
+ break;
+ case TYPE_BASIC:
+@@ -443,7 +450,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ {
+ case TYPE_ARRAY:
+ {
+- type_t *elem = type_array_get_element(t);
++ type_t *elem = type_array_get_element_type(t);
+ if (type_array_is_decl_as_ptr(t))
+ {
+ if (!type_is_alias(elem) && is_array(elem) && !type_array_is_decl_as_ptr(elem))
+@@ -461,7 +468,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ }
+ case TYPE_POINTER:
+ {
+- type_t *ref = type_pointer_get_ref(t);
++ type_t *ref = type_pointer_get_ref_type(t);
+ if (!type_is_alias(ref) && is_array(ref) && !type_array_is_decl_as_ptr(ref))
+ fprintf(h, ")");
+ write_type_right(h, ref, FALSE);
+@@ -485,30 +492,33 @@ void write_type_right(FILE *h, type_t *t, int is_field)
+ }
+ }
+
+-static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
++static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name)
+ {
++ type_t *t = ds->type;
+ type_t *pt = NULL;
+ int ptr_level = 0;
+
+ if (!h) return;
+
+ if (t) {
+- for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
++ const decl_spec_t *dpt = NULL;
++ for (dpt = ds; is_ptr(dpt->type); dpt = type_pointer_get_ref(dpt->type), ptr_level++)
+ ;
++ pt = dpt->type;
+
+ if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
+ int i;
+ const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
+ if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
+- if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
+- write_type_left(h, type_function_get_rettype(pt), NAME_DEFAULT, declonly);
++ if (!is_ptr(ds->type) && dpt->funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(h, "inline ");
++ write_declspec_left(h, type_function_get_retdeclspec(pt), NAME_DEFAULT, declonly);
+ fputc(' ', h);
+ if (ptr_level) fputc('(', h);
+ if (callconv) fprintf(h, "%s ", callconv);
+ for (i = 0; i < ptr_level; i++)
+ fputc('*', h);
+ } else
+- write_type_left(h, t, NAME_DEFAULT, declonly);
++ write_declspec_left(h, ds, NAME_DEFAULT, declonly);
+ }
+
+ if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
+@@ -529,12 +539,7 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c
+ }
+ }
+
+-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
+-{
+- write_type_v(f, t, field, FALSE, name);
+-}
+-
+-static void write_type_definition(FILE *f, type_t *t)
++static void write_type_definition(FILE *f, type_t *t, int declonly)
+ {
+ int in_namespace = t->namespace && !is_global_namespace(t->namespace);
+ int save_written = t->written;
+@@ -545,14 +550,14 @@ static void write_type_definition(FILE *f, type_t *t)
+ write_namespace_start(f, t->namespace);
+ }
+ indent(f, 0);
+- write_type_left(f, t, NAME_DEFAULT, FALSE);
++ write_type_left(f, t, NAME_DEFAULT, declonly);
+ fprintf(f, ";\n");
+ if(in_namespace) {
+ t->written = save_written;
+ write_namespace_end(f, t->namespace);
+ fprintf(f, "extern \"C\" {\n");
+ fprintf(f, "#else\n");
+- write_type_left(f, t, NAME_C, FALSE);
++ write_type_left(f, t, NAME_C, declonly);
+ fprintf(f, ";\n");
+ fprintf(f, "#endif\n\n");
+ }
+@@ -560,12 +565,18 @@ static void write_type_definition(FILE *f, type_t *t)
+
+ void write_type_decl(FILE *f, type_t *t, const char *name)
+ {
+- write_type_v(f, t, FALSE, TRUE, name);
++ decl_spec_t ds;
++ write_declspec_decl(f, init_declspec(&ds, t), name);
++}
++
++void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name)
++{
++ write_type_v(f, ds, FALSE, TRUE, name);
+ }
+
+-void write_type_decl_left(FILE *f, type_t *t)
++void write_declspec_decl_left(FILE *f, const decl_spec_t *ds)
+ {
+- write_type_left(f, t, NAME_DEFAULT, TRUE);
++ write_declspec_left(f, ds, NAME_DEFAULT, TRUE);
+ }
+
+ static int user_type_registered(const char *name)
+@@ -602,8 +613,8 @@ unsigned int get_context_handle_offset( const type_t *type )
+
+ while (!is_attr( type->attrs, ATTR_CONTEXTHANDLE ))
+ {
+- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+- else if (is_ptr( type )) type = type_pointer_get_ref( type );
++ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
++ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
+ else error( "internal error: %s is not a context handle\n", type->name );
+ }
+ LIST_FOR_EACH_ENTRY( ch, &context_handle_list, context_handle_t, entry )
+@@ -622,8 +633,8 @@ unsigned int get_generic_handle_offset( const type_t *type )
+
+ while (!is_attr( type->attrs, ATTR_HANDLE ))
+ {
+- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
+- else if (is_ptr( type )) type = type_pointer_get_ref( type );
++ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
++ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
+ else error( "internal error: %s is not a generic handle\n", type->name );
+ }
+ LIST_FOR_EACH_ENTRY( gh, &generic_handle_list, generic_handle_t, entry )
+@@ -637,82 +648,77 @@ unsigned int get_generic_handle_offset( const type_t *type )
+
+ /* check for types which require additional prototypes to be generated in the
+ * header */
+-void check_for_additional_prototype_types(const var_list_t *list)
+-{
+- const var_t *v;
+-
+- if (!list) return;
+- LIST_FOR_EACH_ENTRY( v, list, const var_t, entry )
+- {
+- type_t *type = v->type;
+- if (!type) continue;
+- for (;;) {
+- const char *name = type->name;
+- if (type->user_types_registered) break;
+- type->user_types_registered = 1;
+- if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
+- if (!context_handle_registered(name))
+- {
+- context_handle_t *ch = xmalloc(sizeof(*ch));
+- ch->name = xstrdup(name);
+- list_add_tail(&context_handle_list, &ch->entry);
+- }
+- /* don't carry on parsing fields within this type */
+- break;
+- }
+- if ((type_get_type(type) != TYPE_BASIC ||
+- type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
+- is_attr(type->attrs, ATTR_HANDLE)) {
+- if (!generic_handle_registered(name))
+- {
+- generic_handle_t *gh = xmalloc(sizeof(*gh));
+- gh->name = xstrdup(name);
+- list_add_tail(&generic_handle_list, &gh->entry);
+- }
+- /* don't carry on parsing fields within this type */
+- break;
++void check_for_additional_prototype_types(type_t *type)
++{
++ if (!type) return;
++ for (;;) {
++ const char *name = type->name;
++ if (type->user_types_registered) break;
++ type->user_types_registered = 1;
++ if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
++ if (!context_handle_registered(name))
++ {
++ context_handle_t *ch = xmalloc(sizeof(*ch));
++ ch->name = xstrdup(name);
++ list_add_tail(&context_handle_list, &ch->entry);
+ }
+- if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
+- if (!user_type_registered(name))
+- {
+- user_type_t *ut = xmalloc(sizeof *ut);
+- ut->name = xstrdup(name);
+- list_add_tail(&user_type_list, &ut->entry);
+- }
+- /* don't carry on parsing fields within this type as we are already
+- * using a wire marshaled type */
+- break;
++ /* don't carry on parsing fields within this type */
++ break;
++ }
++ if ((type_get_type(type) != TYPE_BASIC ||
++ type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
++ is_attr(type->attrs, ATTR_HANDLE)) {
++ if (!generic_handle_registered(name))
++ {
++ generic_handle_t *gh = xmalloc(sizeof(*gh));
++ gh->name = xstrdup(name);
++ list_add_tail(&generic_handle_list, &gh->entry);
+ }
+- else if (type_is_complete(type))
++ /* don't carry on parsing fields within this type */
++ break;
++ }
++ if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
++ if (!user_type_registered(name))
+ {
+- var_list_t *vars;
+- switch (type_get_type_detect_alias(type))
+- {
+- case TYPE_ENUM:
+- vars = type_enum_get_values(type);
+- break;
+- case TYPE_STRUCT:
+- vars = type_struct_get_fields(type);
+- break;
+- case TYPE_UNION:
+- vars = type_union_get_cases(type);
+- break;
+- default:
+- vars = NULL;
+- break;
+- }
+- check_for_additional_prototype_types(vars);
++ user_type_t *ut = xmalloc(sizeof *ut);
++ ut->name = xstrdup(name);
++ list_add_tail(&user_type_list, &ut->entry);
+ }
+-
+- if (type_is_alias(type))
+- type = type_alias_get_aliasee(type);
+- else if (is_ptr(type))
+- type = type_pointer_get_ref(type);
+- else if (is_array(type))
+- type = type_array_get_element(type);
+- else
++ /* don't carry on parsing fields within this type as we are already
++ * using a wire marshaled type */
++ break;
++ }
++ else if (type_is_complete(type))
++ {
++ var_list_t *vars;
++ const var_t *v;
++ switch (type_get_type_detect_alias(type))
++ {
++ case TYPE_ENUM:
++ vars = type_enum_get_values(type);
++ break;
++ case TYPE_STRUCT:
++ vars = type_struct_get_fields(type);
+ break;
++ case TYPE_UNION:
++ vars = type_union_get_cases(type);
++ break;
++ default:
++ vars = NULL;
++ break;
++ }
++ if (vars) LIST_FOR_EACH_ENTRY( v, vars, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
+ }
++
++ if (type_is_alias(type))
++ type = type_alias_get_aliasee_type(type);
++ else if (is_ptr(type))
++ type = type_pointer_get_ref_type(type);
++ else if (is_array(type))
++ type = type_array_get_element_type(type);
++ else
++ break;
+ }
+ }
+
+@@ -791,26 +797,26 @@ static void write_generic_handle_routines(FILE *header)
+ }
+ }
+
+-static void write_typedef(FILE *header, type_t *type)
++static void write_typedef(FILE *header, type_t *type, int declonly)
+ {
+ fprintf(header, "typedef ");
+- write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
++ write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name);
+ fprintf(header, ";\n");
+ }
+
+ int is_const_decl(const var_t *var)
+ {
+- const type_t *t;
++ const decl_spec_t *ds;
+ /* strangely, MIDL accepts a const attribute on any pointer in the
+ * 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 (ds = &var->declspec; ;)
+ {
+- if (is_attr(t->attrs, ATTR_CONST))
++ if (ds->typequalifier == TYPE_QUALIFIER_CONST)
+ return TRUE;
+- else if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ else if (is_ptr(ds->type))
++ ds = type_pointer_get_ref(ds->type);
+ else break;
+ }
+ return FALSE;
+@@ -826,7 +832,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 */
+@@ -838,7 +844,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_v(header, &v->declspec, FALSE, FALSE, v->name);
+ fprintf(header, ";\n\n");
+ }
+ }
+@@ -855,9 +861,9 @@ 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))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
+ is_attr(t->attrs, ATTR_HANDLE))
+ return t;
+@@ -868,13 +874,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_function_get_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;
+@@ -884,7 +890,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;
+@@ -893,8 +899,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;
+@@ -909,13 +915,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
+ if (is_attr(var->attrs, ATTR_OUT))
+ return 1;
+
+@@ -995,7 +1001,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;
+ }
+@@ -1035,8 +1041,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_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ") ");
+
+@@ -1047,8 +1053,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_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ")\n");
+ }
+@@ -1078,7 +1084,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_declspec_decl(h, &arg->declspec, arg->name);
+ if (method == 2) {
+ const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE);
+ if (expr) {
+@@ -1090,7 +1096,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;
+@@ -1119,8 +1125,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_function_get_args(func->declspec.type);
+ const var_t *arg;
+
+ if (!callconv) callconv = "STDMETHODCALLTYPE";
+@@ -1130,11 +1136,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_declspec_decl_left(header, type_function_get_retdeclspec(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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " *__ret");
+ --indentation;
+ if (args) {
+@@ -1144,7 +1150,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s(\n", callconv, get_name(func));
+ write_args(header, args, iface->name, 2, TRUE);
+ fprintf(header, ")\n");
+@@ -1152,7 +1158,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " __ret;\n");
+ indent(header, 0);
+ fprintf(header, "return *%s(&__ret", get_name(func));
+@@ -1169,7 +1175,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " %s %s(\n", callconv, get_name(func));
+ write_args(header, args, iface->name, 2, TRUE);
+ fprintf(header, ") = 0;\n");
+@@ -1206,25 +1212,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_declspec_decl_left(header, type_function_get_retdeclspec(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_function_get_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_declspec_decl_left(header, type_function_get_retdeclspec(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_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
+ fprintf(header, ",%s", arg->name);
+ fprintf(header, ");\n");
+ --indentation;
+@@ -1250,10 +1256,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ if (is_aggregate_return(func))
+ fprintf(header, " *");
+ if (is_inherited_method(iface, func))
+@@ -1266,13 +1272,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
+ fprintf(header, " *__ret");
+ }
+ --indentation;
+- if (type_get_function_args(func->type)) {
++ if (type_function_get_args(func->declspec.type)) {
+ fprintf(header, ",\n");
+- write_args(header, type_get_function_args(func->type), name, 0, TRUE);
++ write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE);
+ }
+ fprintf(header, ");\n");
+ fprintf(header, "\n");
+@@ -1299,12 +1305,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_declspec_decl_left(header, type_function_get_retdeclspec(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_function_get_args(func->declspec.type), iface->name, 1, TRUE);
+ fprintf(header, ");\n");
+ /* stub prototype */
+ fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func));
+@@ -1337,12 +1343,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_declspec_decl_left(fp, type_function_get_retdeclspec(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_function_get_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)
+@@ -1359,9 +1365,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_declspec_decl_left(fp, type_function_get_retdeclspec(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_function_get_args(func->declspec.type), iface->name, 1, TRUE);
+ fprintf(fp, ")");
+ if (body)
+ /* Remotable methods must all return HRESULTs. */
+@@ -1407,15 +1413,16 @@ 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_declspec_decl_left(header, type_function_get_retdeclspec(fun->declspec.type));
++ if (fun->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(header, " inline");
+ 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_function_get_args(fun->declspec.type))
++ write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE);
+ else
+ fprintf(header, " void");
+ fprintf(header, ");\n\n");
+@@ -1541,7 +1548,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_declspec_decl( header, &var->declspec, var->name );
+ fprintf(header, ";\n");
+ }
+ if (old_names)
+@@ -1653,6 +1660,7 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
+ if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
+ {
+ type_t *iface = stmt->u.type;
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
+ {
+ write_forward(header, iface);
+@@ -1694,6 +1702,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ {
+ type_t *iface = stmt->u.type;
+ type_t *async_iface = iface->details.iface->async_iface;
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (is_object(iface)) is_object_interface++;
+ if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
+ {
+@@ -1718,7 +1727,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ write_coclass(header, stmt->u.type);
+ else
+ {
+- write_type_definition(header, stmt->u.type);
++ write_type_definition(header, stmt->u.type, stmt->declonly);
+ }
+ break;
+ case STMT_TYPEREF:
+@@ -1739,7 +1748,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
+ {
+ const type_list_t *type_entry = stmt->u.type_list;
+ for (; type_entry; type_entry = type_entry->next)
+- write_typedef(header, type_entry->type);
++ write_typedef(header, type_entry->type, stmt->declonly);
+ break;
+ }
+ case STMT_LIBRARY:
+@@ -1750,7 +1759,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)
+ {
+@@ -1784,15 +1793,15 @@ void write_header(const statement_list_t *stmts)
+ }
+ fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
+
++ fprintf(header, "#ifdef _WIN32\n");
+ fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n");
+ fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\n");
+- fprintf(header, "#endif\n\n");
+-
++ fprintf(header, "#endif\n");
+ fprintf(header, "#include <rpc.h>\n" );
+ fprintf(header, "#include <rpcndr.h>\n" );
+ if (!for_each_serializable(stmts, NULL, serializable_exists))
+ fprintf(header, "#include <midles.h>\n" );
+- fprintf(header, "\n" );
++ fprintf(header, "#endif\n\n");
+
+ fprintf(header, "#ifndef COM_NO_WINDOWS_H\n");
+ fprintf(header, "#include <windows.h>\n");
+diff --git a/mingw-w64-tools/widl/src/header.h b/mingw-w64-tools/widl/src/header.h
+index 0d44b403..0e62f77c 100644
+--- a/mingw-w64-tools/widl/src/header.h
++++ b/mingw-w64-tools/widl/src/header.h
+@@ -29,10 +29,12 @@ extern int is_attr(const attr_list_t *list, enum attr_type t);
+ extern void *get_attrp(const attr_list_t *list, enum attr_type t);
+ extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
+ extern const char* get_name(const var_t *v);
++extern void write_declspec_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly);
+ extern void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly);
+ extern void write_type_right(FILE *h, type_t *t, int is_field);
+ extern void write_type_decl(FILE *f, type_t *t, const char *name);
+-extern void write_type_decl_left(FILE *f, type_t *t);
++extern void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name);
++extern void write_declspec_decl_left(FILE *f, const decl_spec_t *ds);
+ extern unsigned int get_context_handle_offset( const type_t *type );
+ extern unsigned int get_generic_handle_offset( const type_t *type );
+ extern int needs_space_after(type_t *t);
+@@ -83,12 +85,12 @@ static inline int is_conformant_array(const type_t *t)
+
+ static inline int last_ptr(const type_t *type)
+ {
+- return is_ptr(type) && !is_declptr(type_pointer_get_ref(type));
++ return is_ptr(type) && !is_declptr(type_pointer_get_ref_type(type));
+ }
+
+ static inline int last_array(const type_t *type)
+ {
+- return is_array(type) && !is_array(type_array_get_element(type));
++ return is_array(type) && !is_array(type_array_get_element_type(type));
+ }
+
+ static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
+@@ -102,7 +104,7 @@ static inline int is_context_handle(const type_t *type)
+ const type_t *t;
+ for (t = type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+ return 1;
+ return 0;
+diff --git a/mingw-w64-tools/widl/src/parser.tab.c b/mingw-w64-tools/widl/src/parser.tab.c
+index 6266e054..d7053e79 100644
+--- a/mingw-w64-tools/widl/src/parser.tab.c
++++ b/mingw-w64-tools/widl/src/parser.tab.c
+@@ -1,8 +1,8 @@
+-/* A Bison parser, made by GNU Bison 3.0.5. */
++/* A Bison parser, made by GNU Bison 3.0.4. */
+
+ /* Bison implementation for Yacc-like parsers in C
+
+- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
++ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+@@ -44,7 +44,7 @@
+ #define YYBISON 1
+
+ /* Bison version. */
+-#define YYBISON_VERSION "3.0.5"
++#define YYBISON_VERSION "3.0.4"
+
+ /* Skeleton name. */
+ #define YYSKELETON_NAME "yacc.c"
+@@ -125,13 +125,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);
+@@ -140,7 +133,7 @@ static void fix_incomplete_types(type_t *complete_type);
+ static str_list_t *append_str(str_list_t *list, char *str);
+ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
+ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
+ static attr_t *make_attr(enum attr_type type);
+ static attr_t *make_attrv(enum attr_type type, unsigned int val);
+ static attr_t *make_attrp(enum attr_type type, void *val);
+@@ -156,6 +149,7 @@ static declarator_t *make_declarator(var_t *var);
+ static type_t *make_safearray(type_t *type);
+ static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+ static type_t *append_chain_type(type_t *chain, type_t *type);
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
+ static warning_list_t *append_warning(warning_list_t *, int);
+
+ static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+@@ -212,7 +206,7 @@ static struct namespace *current_namespace = &global_namespace;
+ static typelib_t *current_typelib;
+
+
+-#line 216 "parser.tab.c" /* yacc.c:339 */
++#line 210 "parser.tab.c" /* yacc.c:339 */
+
+ # ifndef YY_NULLPTR
+ # if defined __cplusplus && 201103L <= __cplusplus
+@@ -438,7 +432,7 @@ extern int parser_debug;
+
+ union YYSTYPE
+ {
+-#line 142 "parser.y" /* yacc.c:355 */
++#line 136 "parser.y" /* yacc.c:355 */
+
+ attr_t *attr;
+ attr_list_t *attr_list;
+@@ -465,8 +459,10 @@ union YYSTYPE
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+
+-#line 470 "parser.tab.c" /* yacc.c:355 */
++#line 466 "parser.tab.c" /* yacc.c:355 */
+ };
+
+ typedef union YYSTYPE YYSTYPE;
+@@ -483,7 +479,7 @@ int parser_parse (void);
+
+ /* Copy the second part of user declarations. */
+
+-#line 487 "parser.tab.c" /* yacc.c:358 */
++#line 483 "parser.tab.c" /* yacc.c:358 */
+
+ #ifdef short
+ # undef short
+@@ -799,48 +795,48 @@ static const yytype_uint8 yytranslate[] =
+ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
+ static const yytype_uint16 yyrline[] =
+ {
+- 0, 325, 325, 340, 340, 342, 343, 343, 345, 346,
+- 347, 350, 353, 354, 355, 358, 359, 360, 360, 362,
+- 363, 364, 367, 368, 369, 370, 373, 374, 377, 378,
+- 382, 383, 384, 385, 386, 387, 388, 391, 402, 403,
+- 407, 408, 409, 410, 411, 412, 413, 414, 415, 418,
+- 420, 428, 434, 438, 439, 441, 445, 449, 450, 453,
+- 454, 457, 458, 462, 467, 474, 478, 479, 482, 483,
+- 487, 490, 491, 492, 495, 496, 499, 500, 501, 502,
+- 503, 504, 505, 506, 507, 508, 509, 510, 511, 512,
+- 513, 514, 515, 516, 517, 518, 519, 520, 521, 522,
+- 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
+- 533, 534, 535, 536, 537, 538, 539, 540, 541, 542,
+- 543, 544, 545, 546, 547, 548, 549, 550, 551, 552,
+- 553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
+- 563, 564, 565, 566, 567, 568, 569, 570, 571, 572,
+- 573, 574, 578, 579, 580, 581, 582, 583, 584, 585,
+- 586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
+- 596, 597, 598, 599, 600, 601, 605, 606, 611, 612,
+- 613, 614, 617, 618, 621, 625, 631, 632, 633, 636,
+- 640, 652, 656, 661, 664, 665, 668, 669, 672, 673,
+- 674, 675, 676, 677, 678, 679, 680, 681, 682, 683,
+- 684, 685, 686, 687, 688, 689, 690, 691, 692, 693,
+- 694, 695, 696, 697, 698, 699, 700, 701, 702, 703,
+- 704, 705, 706, 707, 708, 709, 711, 713, 714, 717,
+- 718, 721, 727, 733, 734, 737, 742, 749, 750, 753,
+- 754, 758, 759, 762, 766, 772, 780, 784, 789, 790,
+- 793, 794, 795, 798, 800, 803, 804, 805, 806, 807,
+- 808, 809, 810, 811, 812, 813, 816, 817, 820, 821,
+- 822, 823, 824, 825, 826, 827, 828, 831, 832, 840,
+- 846, 850, 853, 854, 858, 861, 862, 865, 874, 875,
+- 878, 879, 882, 888, 894, 895, 898, 899, 902, 912,
+- 922, 928, 932, 933, 936, 937, 940, 945, 952, 953,
+- 954, 958, 962, 965, 966, 969, 970, 974, 975, 979,
+- 980, 981, 985, 987, 989, 993, 994, 995, 996, 1004,
+- 1006, 1008, 1013, 1015, 1020, 1021, 1026, 1027, 1028, 1029,
+- 1034, 1043, 1045, 1046, 1051, 1053, 1057, 1058, 1065, 1066,
+- 1067, 1068, 1069, 1074, 1082, 1083, 1086, 1087, 1090, 1097,
+- 1098, 1103, 1104, 1108, 1109, 1110, 1111, 1112, 1116, 1117,
+- 1118, 1121, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131,
+- 1132, 1133, 1136, 1143, 1145, 1151, 1152, 1153, 1156, 1158,
+- 1160, 1162, 1165, 1170, 1178, 1179, 1182, 1183, 1186, 1187,
+- 1188
++ 0, 323, 323, 338, 338, 340, 341, 341, 343, 344,
++ 345, 348, 351, 352, 353, 356, 357, 358, 358, 360,
++ 361, 362, 365, 366, 367, 368, 371, 372, 375, 376,
++ 380, 381, 382, 383, 384, 385, 386, 389, 400, 401,
++ 405, 406, 407, 408, 409, 410, 411, 412, 413, 416,
++ 418, 426, 432, 436, 437, 439, 443, 447, 448, 451,
++ 452, 455, 456, 460, 465, 472, 476, 477, 480, 481,
++ 485, 488, 489, 490, 493, 494, 497, 498, 499, 500,
++ 501, 502, 503, 504, 505, 506, 507, 508, 509, 510,
++ 511, 512, 513, 514, 515, 516, 517, 518, 519, 520,
++ 521, 522, 523, 524, 525, 526, 527, 528, 529, 530,
++ 531, 532, 533, 534, 535, 536, 537, 538, 539, 540,
++ 541, 542, 543, 544, 545, 546, 547, 548, 549, 550,
++ 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
++ 561, 562, 563, 564, 565, 566, 567, 568, 569, 570,
++ 571, 572, 576, 577, 578, 579, 580, 581, 582, 583,
++ 584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
++ 594, 595, 596, 597, 598, 599, 603, 604, 609, 610,
++ 611, 612, 615, 616, 619, 623, 629, 630, 631, 634,
++ 638, 650, 654, 659, 662, 663, 666, 667, 670, 671,
++ 672, 673, 674, 675, 676, 677, 678, 679, 680, 681,
++ 682, 683, 684, 685, 686, 687, 688, 689, 690, 691,
++ 692, 693, 694, 695, 696, 697, 698, 699, 700, 701,
++ 702, 703, 704, 705, 706, 707, 709, 711, 712, 715,
++ 716, 719, 725, 731, 732, 735, 740, 747, 748, 751,
++ 752, 756, 757, 760, 764, 770, 778, 782, 787, 788,
++ 791, 792, 793, 796, 798, 801, 802, 803, 804, 805,
++ 806, 807, 808, 809, 810, 811, 814, 815, 818, 819,
++ 820, 821, 822, 823, 824, 825, 826, 829, 830, 838,
++ 844, 848, 851, 852, 856, 859, 860, 863, 872, 873,
++ 876, 877, 880, 886, 892, 893, 896, 897, 900, 910,
++ 920, 926, 930, 931, 934, 935, 938, 943, 950, 951,
++ 952, 956, 960, 963, 964, 967, 968, 972, 973, 977,
++ 978, 979, 983, 985, 987, 991, 992, 993, 994, 1002,
++ 1004, 1006, 1011, 1013, 1018, 1019, 1024, 1025, 1026, 1027,
++ 1032, 1041, 1043, 1044, 1049, 1051, 1055, 1056, 1063, 1064,
++ 1065, 1066, 1067, 1072, 1080, 1081, 1084, 1085, 1088, 1095,
++ 1096, 1101, 1102, 1106, 1107, 1108, 1109, 1110, 1114, 1115,
++ 1116, 1119, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129,
++ 1130, 1131, 1134, 1141, 1143, 1149, 1150, 1151, 1154, 1156,
++ 1158, 1160, 1163, 1168, 1176, 1177, 1180, 1181, 1184, 1185,
++ 1186
+ };
+ #endif
+
+@@ -903,7 +899,7 @@ static const char *const yytname[] =
+ "dispinterfacedef", "inherit", "interface", "interfacehdr",
+ "interfacedef", "interfacedec", "module", "modulehdr", "moduledef",
+ "storage_cls_spec", "function_specifier", "type_qualifier",
+- "m_type_qual_list", "decl_spec", "m_decl_spec_no_type",
++ "m_type_qual_bits", "decl_spec", "m_decl_spec_no_type",
+ "decl_spec_no_type", "declarator", "direct_declarator",
+ "abstract_declarator", "abstract_declarator_no_direct",
+ "m_abstract_declarator", "abstract_direct_declarator", "any_declarator",
+@@ -2298,7 +2294,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+ case N: \
+ yyformat = S; \
+ break
+- default: /* Avoid compiler warnings. */
+ YYCASE_(0, YY_("syntax error"));
+ YYCASE_(1, YY_("syntax error, unexpected %s"));
+ YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+@@ -2615,7 +2610,7 @@ yyreduce:
+ switch (yyn)
+ {
+ case 2:
+-#line 325 "parser.y" /* yacc.c:1648 */
++#line 323 "parser.y" /* yacc.c:1646 */
+ { fix_incomplete();
+ check_statements((yyvsp[-1].stmt_list), FALSE);
+ check_all_user_types((yyvsp[-1].stmt_list));
+@@ -2629,197 +2624,197 @@ yyreduce:
+ write_dlldata((yyvsp[-1].stmt_list));
+ write_local_stubs((yyvsp[-1].stmt_list));
+ }
+-#line 2633 "parser.tab.c" /* yacc.c:1648 */
++#line 2628 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 5:
+-#line 342 "parser.y" /* yacc.c:1648 */
++#line 340 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2639 "parser.tab.c" /* yacc.c:1648 */
++#line 2634 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 6:
+-#line 343 "parser.y" /* yacc.c:1648 */
++#line 341 "parser.y" /* yacc.c:1646 */
+ { push_namespace((yyvsp[-1].str)); }
+-#line 2645 "parser.tab.c" /* yacc.c:1648 */
++#line 2640 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 7:
+-#line 344 "parser.y" /* yacc.c:1648 */
++#line 342 "parser.y" /* yacc.c:1646 */
+ { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
+-#line 2651 "parser.tab.c" /* yacc.c:1648 */
++#line 2646 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 8:
+-#line 345 "parser.y" /* yacc.c:1648 */
++#line 343 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
+-#line 2657 "parser.tab.c" /* yacc.c:1648 */
++#line 2652 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 9:
+-#line 346 "parser.y" /* yacc.c:1648 */
++#line 344 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
+-#line 2663 "parser.tab.c" /* yacc.c:1648 */
++#line 2658 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 10:
+-#line 347 "parser.y" /* yacc.c:1648 */
++#line 345 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = (yyvsp[-2].stmt_list);
+ reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0);
+ }
+-#line 2671 "parser.tab.c" /* yacc.c:1648 */
++#line 2666 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 11:
+-#line 350 "parser.y" /* yacc.c:1648 */
++#line 348 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
+ reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
+ }
+-#line 2679 "parser.tab.c" /* yacc.c:1648 */
++#line 2674 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 12:
+-#line 353 "parser.y" /* yacc.c:1648 */
++#line 351 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
+-#line 2685 "parser.tab.c" /* yacc.c:1648 */
++#line 2680 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 13:
+-#line 354 "parser.y" /* yacc.c:1648 */
++#line 352 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
+-#line 2691 "parser.tab.c" /* yacc.c:1648 */
++#line 2686 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 14:
+-#line 355 "parser.y" /* yacc.c:1648 */
++#line 353 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2697 "parser.tab.c" /* yacc.c:1648 */
++#line 2692 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 15:
+-#line 358 "parser.y" /* yacc.c:1648 */
++#line 356 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2703 "parser.tab.c" /* yacc.c:1648 */
++#line 2698 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 16:
+-#line 359 "parser.y" /* yacc.c:1648 */
++#line 357 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
+-#line 2709 "parser.tab.c" /* yacc.c:1648 */
++#line 2704 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 17:
+-#line 360 "parser.y" /* yacc.c:1648 */
++#line 358 "parser.y" /* yacc.c:1646 */
+ { push_namespace((yyvsp[-1].str)); }
+-#line 2715 "parser.tab.c" /* yacc.c:1648 */
++#line 2710 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 18:
+-#line 361 "parser.y" /* yacc.c:1648 */
++#line 359 "parser.y" /* yacc.c:1646 */
+ { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
+-#line 2721 "parser.tab.c" /* yacc.c:1648 */
++#line 2716 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 19:
+-#line 362 "parser.y" /* yacc.c:1648 */
++#line 360 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
+-#line 2727 "parser.tab.c" /* yacc.c:1648 */
++#line 2722 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 20:
+-#line 363 "parser.y" /* yacc.c:1648 */
++#line 361 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = (yyvsp[-2].stmt_list); reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0); }
+-#line 2733 "parser.tab.c" /* yacc.c:1648 */
++#line 2728 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 21:
+-#line 364 "parser.y" /* yacc.c:1648 */
++#line 362 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
+ reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
+ }
+-#line 2741 "parser.tab.c" /* yacc.c:1648 */
++#line 2736 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 22:
+-#line 367 "parser.y" /* yacc.c:1648 */
++#line 365 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
+-#line 2747 "parser.tab.c" /* yacc.c:1648 */
++#line 2742 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 23:
+-#line 368 "parser.y" /* yacc.c:1648 */
++#line 366 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2753 "parser.tab.c" /* yacc.c:1648 */
++#line 2748 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 24:
+-#line 369 "parser.y" /* yacc.c:1648 */
++#line 367 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_importlib((yyvsp[0].str))); }
+-#line 2759 "parser.tab.c" /* yacc.c:1648 */
++#line 2754 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 25:
+-#line 370 "parser.y" /* yacc.c:1648 */
++#line 368 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
+-#line 2765 "parser.tab.c" /* yacc.c:1648 */
++#line 2760 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 26:
+-#line 373 "parser.y" /* yacc.c:1648 */
++#line 371 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = NULL; }
+-#line 2771 "parser.tab.c" /* yacc.c:1648 */
++#line 2766 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 27:
+-#line 374 "parser.y" /* yacc.c:1648 */
++#line 372 "parser.y" /* yacc.c:1646 */
+ { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
+-#line 2777 "parser.tab.c" /* yacc.c:1648 */
++#line 2772 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 30:
+-#line 382 "parser.y" /* yacc.c:1648 */
++#line 380 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_cppquote((yyvsp[0].str)); }
+-#line 2783 "parser.tab.c" /* yacc.c:1648 */
++#line 2778 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 31:
+-#line 383 "parser.y" /* yacc.c:1648 */
++#line 381 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_type_decl((yyvsp[-1].type)); }
+-#line 2789 "parser.tab.c" /* yacc.c:1648 */
++#line 2784 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 32:
+-#line 384 "parser.y" /* yacc.c:1648 */
++#line 382 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_declaration((yyvsp[-1].var)); }
+-#line 2795 "parser.tab.c" /* yacc.c:1648 */
++#line 2790 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 33:
+-#line 385 "parser.y" /* yacc.c:1648 */
++#line 383 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_import((yyvsp[0].str)); }
+-#line 2801 "parser.tab.c" /* yacc.c:1648 */
++#line 2796 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 34:
+-#line 386 "parser.y" /* yacc.c:1648 */
++#line 384 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = (yyvsp[-1].statement); }
+-#line 2807 "parser.tab.c" /* yacc.c:1648 */
++#line 2802 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 35:
+-#line 387 "parser.y" /* yacc.c:1648 */
++#line 385 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = make_statement_pragma((yyvsp[0].str)); }
+-#line 2813 "parser.tab.c" /* yacc.c:1648 */
++#line 2808 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 36:
+-#line 388 "parser.y" /* yacc.c:1648 */
++#line 386 "parser.y" /* yacc.c:1646 */
+ { (yyval.statement) = NULL; }
+-#line 2819 "parser.tab.c" /* yacc.c:1648 */
++#line 2814 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 37:
+-#line 392 "parser.y" /* yacc.c:1648 */
++#line 390 "parser.y" /* yacc.c:1646 */
+ {
+ int result;
+ (yyval.statement) = NULL;
+@@ -2827,909 +2822,909 @@ yyreduce:
+ if(!result)
+ error_loc("expected \"disable\" or \"enable\"\n");
+ }
+-#line 2831 "parser.tab.c" /* yacc.c:1648 */
++#line 2826 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 38:
+-#line 402 "parser.y" /* yacc.c:1648 */
++#line 400 "parser.y" /* yacc.c:1646 */
+ { (yyval.warning_list) = append_warning(NULL, (yyvsp[0].num)); }
+-#line 2837 "parser.tab.c" /* yacc.c:1648 */
++#line 2832 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 39:
+-#line 403 "parser.y" /* yacc.c:1648 */
++#line 401 "parser.y" /* yacc.c:1646 */
+ { (yyval.warning_list) = append_warning((yyvsp[-1].warning_list), (yyvsp[0].num)); }
+-#line 2843 "parser.tab.c" /* yacc.c:1648 */
++#line 2838 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 41:
+-#line 408 "parser.y" /* yacc.c:1648 */
++#line 406 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 2849 "parser.tab.c" /* yacc.c:1648 */
++#line 2844 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 43:
+-#line 410 "parser.y" /* yacc.c:1648 */
++#line 408 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 2855 "parser.tab.c" /* yacc.c:1648 */
++#line 2850 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 45:
+-#line 412 "parser.y" /* yacc.c:1648 */
++#line 410 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
+-#line 2861 "parser.tab.c" /* yacc.c:1648 */
++#line 2856 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 46:
+-#line 413 "parser.y" /* yacc.c:1648 */
++#line 411 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_enum_attrs((yyvsp[-1].attr_list)); }
+-#line 2867 "parser.tab.c" /* yacc.c:1648 */
++#line 2862 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 47:
+-#line 414 "parser.y" /* yacc.c:1648 */
++#line 412 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_struct_attrs((yyvsp[-1].attr_list)); }
+-#line 2873 "parser.tab.c" /* yacc.c:1648 */
++#line 2868 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 48:
+-#line 415 "parser.y" /* yacc.c:1648 */
++#line 413 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_union_attrs((yyvsp[-1].attr_list)); }
+-#line 2879 "parser.tab.c" /* yacc.c:1648 */
++#line 2874 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 49:
+-#line 418 "parser.y" /* yacc.c:1648 */
++#line 416 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-1].str); }
+-#line 2885 "parser.tab.c" /* yacc.c:1648 */
++#line 2880 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 50:
+-#line 420 "parser.y" /* yacc.c:1648 */
++#line 418 "parser.y" /* yacc.c:1646 */
+ { assert(yychar == YYEMPTY);
+ (yyval.import) = xmalloc(sizeof(struct _import_t));
+ (yyval.import)->name = (yyvsp[-1].str);
+ (yyval.import)->import_performed = do_import((yyvsp[-1].str));
+ if (!(yyval.import)->import_performed) yychar = aEOF;
+ }
+-#line 2896 "parser.tab.c" /* yacc.c:1648 */
++#line 2891 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 51:
+-#line 428 "parser.y" /* yacc.c:1648 */
++#line 426 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-2].import)->name;
+ if ((yyvsp[-2].import)->import_performed) pop_import();
+ free((yyvsp[-2].import));
+ }
+-#line 2905 "parser.tab.c" /* yacc.c:1648 */
++#line 2900 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 52:
+-#line 435 "parser.y" /* yacc.c:1648 */
++#line 433 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[-2].str); if(!parse_only) add_importlib((yyvsp[-2].str), current_typelib); }
+-#line 2911 "parser.tab.c" /* yacc.c:1648 */
++#line 2906 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 53:
+-#line 438 "parser.y" /* yacc.c:1648 */
++#line 436 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 2917 "parser.tab.c" /* yacc.c:1648 */
++#line 2912 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 54:
+-#line 439 "parser.y" /* yacc.c:1648 */
++#line 437 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 2923 "parser.tab.c" /* yacc.c:1648 */
++#line 2918 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 55:
+-#line 441 "parser.y" /* yacc.c:1648 */
++#line 439 "parser.y" /* yacc.c:1646 */
+ { (yyval.typelib) = make_library((yyvsp[-1].str), check_library_attrs((yyvsp[-1].str), (yyvsp[-2].attr_list)));
+ if (!parse_only && do_typelib) current_typelib = (yyval.typelib);
+ }
+-#line 2931 "parser.tab.c" /* yacc.c:1648 */
++#line 2926 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 56:
+-#line 446 "parser.y" /* yacc.c:1648 */
++#line 444 "parser.y" /* yacc.c:1646 */
+ { (yyval.typelib) = (yyvsp[-3].typelib); (yyval.typelib)->stmts = (yyvsp[-2].stmt_list); }
+-#line 2937 "parser.tab.c" /* yacc.c:1648 */
++#line 2932 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 57:
+-#line 449 "parser.y" /* yacc.c:1648 */
++#line 447 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 2943 "parser.tab.c" /* yacc.c:1648 */
++#line 2938 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 59:
+-#line 453 "parser.y" /* yacc.c:1648 */
++#line 451 "parser.y" /* yacc.c:1646 */
+ { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); }
+-#line 2949 "parser.tab.c" /* yacc.c:1648 */
++#line 2944 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 60:
+-#line 454 "parser.y" /* yacc.c:1648 */
++#line 452 "parser.y" /* yacc.c:1646 */
+ { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) ); }
+-#line 2955 "parser.tab.c" /* yacc.c:1648 */
++#line 2950 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 62:
+-#line 458 "parser.y" /* yacc.c:1648 */
++#line 456 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), make_var(strdup("...")) ); }
+-#line 2961 "parser.tab.c" /* yacc.c:1648 */
++#line 2956 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 63:
+-#line 462 "parser.y" /* yacc.c:1648 */
++#line 460 "parser.y" /* yacc.c:1646 */
+ { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+ error_loc("invalid storage class for function parameter\n");
+ (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+ free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
+ }
+-#line 2971 "parser.tab.c" /* yacc.c:1648 */
++#line 2966 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 64:
+-#line 467 "parser.y" /* yacc.c:1648 */
++#line 465 "parser.y" /* yacc.c:1646 */
+ { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+ error_loc("invalid storage class for function parameter\n");
+ (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+ free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
+ }
+-#line 2981 "parser.tab.c" /* yacc.c:1648 */
++#line 2976 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 65:
+-#line 474 "parser.y" /* yacc.c:1648 */
++#line 472 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[-1].expr);
+ if (!(yyval.expr)->is_const || (yyval.expr)->cval <= 0)
+ error_loc("array dimension is not a positive integer constant\n");
+ }
+-#line 2990 "parser.tab.c" /* yacc.c:1648 */
++#line 2985 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 66:
+-#line 478 "parser.y" /* yacc.c:1648 */
++#line 476 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 2996 "parser.tab.c" /* yacc.c:1648 */
++#line 2991 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 67:
+-#line 479 "parser.y" /* yacc.c:1648 */
++#line 477 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 3002 "parser.tab.c" /* yacc.c:1648 */
++#line 2997 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 68:
+-#line 482 "parser.y" /* yacc.c:1648 */
++#line 480 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = NULL; }
+-#line 3008 "parser.tab.c" /* yacc.c:1648 */
++#line 3003 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 70:
+-#line 487 "parser.y" /* yacc.c:1648 */
++#line 485 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = (yyvsp[-1].attr_list); }
+-#line 3014 "parser.tab.c" /* yacc.c:1648 */
++#line 3009 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 71:
+-#line 490 "parser.y" /* yacc.c:1648 */
++#line 488 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); }
+-#line 3020 "parser.tab.c" /* yacc.c:1648 */
++#line 3015 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 72:
+-#line 491 "parser.y" /* yacc.c:1648 */
++#line 489 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); }
+-#line 3026 "parser.tab.c" /* yacc.c:1648 */
++#line 3021 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 73:
+-#line 492 "parser.y" /* yacc.c:1648 */
++#line 490 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); }
+-#line 3032 "parser.tab.c" /* yacc.c:1648 */
++#line 3027 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 74:
+-#line 495 "parser.y" /* yacc.c:1648 */
++#line 493 "parser.y" /* yacc.c:1646 */
+ { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); }
+-#line 3038 "parser.tab.c" /* yacc.c:1648 */
++#line 3033 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 75:
+-#line 496 "parser.y" /* yacc.c:1648 */
++#line 494 "parser.y" /* yacc.c:1646 */
+ { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); }
+-#line 3044 "parser.tab.c" /* yacc.c:1648 */
++#line 3039 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 76:
+-#line 499 "parser.y" /* yacc.c:1648 */
++#line 497 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = NULL; }
+-#line 3050 "parser.tab.c" /* yacc.c:1648 */
++#line 3045 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 77:
+-#line 500 "parser.y" /* yacc.c:1648 */
++#line 498 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); }
+-#line 3056 "parser.tab.c" /* yacc.c:1648 */
++#line 3051 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 78:
+-#line 501 "parser.y" /* yacc.c:1648 */
++#line 499 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ANNOTATION, (yyvsp[-1].str)); }
+-#line 3062 "parser.tab.c" /* yacc.c:1648 */
++#line 3057 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 79:
+-#line 502 "parser.y" /* yacc.c:1648 */
++#line 500 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_APPOBJECT); }
+-#line 3068 "parser.tab.c" /* yacc.c:1648 */
++#line 3063 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 80:
+-#line 503 "parser.y" /* yacc.c:1648 */
++#line 501 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ASYNC); }
+-#line 3074 "parser.tab.c" /* yacc.c:1648 */
++#line 3069 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 81:
+-#line 504 "parser.y" /* yacc.c:1648 */
++#line 502 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); }
+-#line 3080 "parser.tab.c" /* yacc.c:1648 */
++#line 3075 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 82:
+-#line 505 "parser.y" /* yacc.c:1648 */
++#line 503 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_BINDABLE); }
+-#line 3086 "parser.tab.c" /* yacc.c:1648 */
++#line 3081 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 83:
+-#line 506 "parser.y" /* yacc.c:1648 */
++#line 504 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_BROADCAST); }
+-#line 3092 "parser.tab.c" /* yacc.c:1648 */
++#line 3087 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 84:
+-#line 507 "parser.y" /* yacc.c:1648 */
++#line 505 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); }
+-#line 3098 "parser.tab.c" /* yacc.c:1648 */
++#line 3093 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 85:
+-#line 508 "parser.y" /* yacc.c:1648 */
++#line 506 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); }
+-#line 3104 "parser.tab.c" /* yacc.c:1648 */
++#line 3099 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 86:
+-#line 509 "parser.y" /* yacc.c:1648 */
++#line 507 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_CODE); }
+-#line 3110 "parser.tab.c" /* yacc.c:1648 */
++#line 3105 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 87:
+-#line 510 "parser.y" /* yacc.c:1648 */
++#line 508 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_COMMSTATUS); }
+-#line 3116 "parser.tab.c" /* yacc.c:1648 */
++#line 3111 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 88:
+-#line 511 "parser.y" /* yacc.c:1648 */
++#line 509 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); }
+-#line 3122 "parser.tab.c" /* yacc.c:1648 */
++#line 3117 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 89:
+-#line 512 "parser.y" /* yacc.c:1648 */
++#line 510 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
+-#line 3128 "parser.tab.c" /* yacc.c:1648 */
++#line 3123 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 90:
+-#line 513 "parser.y" /* yacc.c:1648 */
++#line 511 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
+-#line 3134 "parser.tab.c" /* yacc.c:1648 */
++#line 3129 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 91:
+-#line 514 "parser.y" /* yacc.c:1648 */
++#line 512 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_CONTROL); }
+-#line 3140 "parser.tab.c" /* yacc.c:1648 */
++#line 3135 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 92:
+-#line 515 "parser.y" /* yacc.c:1648 */
++#line 513 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DECODE); }
+-#line 3146 "parser.tab.c" /* yacc.c:1648 */
++#line 3141 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 93:
+-#line 516 "parser.y" /* yacc.c:1648 */
++#line 514 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULT); }
+-#line 3152 "parser.tab.c" /* yacc.c:1648 */
++#line 3147 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 94:
+-#line 517 "parser.y" /* yacc.c:1648 */
++#line 515 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTBIND); }
+-#line 3158 "parser.tab.c" /* yacc.c:1648 */
++#line 3153 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 95:
+-#line 518 "parser.y" /* yacc.c:1648 */
++#line 516 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); }
+-#line 3164 "parser.tab.c" /* yacc.c:1648 */
++#line 3159 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 96:
+-#line 519 "parser.y" /* yacc.c:1648 */
++#line 517 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE, (yyvsp[-1].expr)); }
+-#line 3170 "parser.tab.c" /* yacc.c:1648 */
++#line 3165 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 97:
+-#line 520 "parser.y" /* yacc.c:1648 */
++#line 518 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); }
+-#line 3176 "parser.tab.c" /* yacc.c:1648 */
++#line 3171 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 98:
+-#line 521 "parser.y" /* yacc.c:1648 */
++#line 519 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DISABLECONSISTENCYCHECK); }
+-#line 3182 "parser.tab.c" /* yacc.c:1648 */
++#line 3177 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 99:
+-#line 522 "parser.y" /* yacc.c:1648 */
++#line 520 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); }
+-#line 3188 "parser.tab.c" /* yacc.c:1648 */
++#line 3183 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 100:
+-#line 523 "parser.y" /* yacc.c:1648 */
++#line 521 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); }
+-#line 3194 "parser.tab.c" /* yacc.c:1648 */
++#line 3189 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 101:
+-#line 524 "parser.y" /* yacc.c:1648 */
++#line 522 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DUAL); }
+-#line 3200 "parser.tab.c" /* yacc.c:1648 */
++#line 3195 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 102:
+-#line 525 "parser.y" /* yacc.c:1648 */
++#line 523 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENABLEALLOCATE); }
+-#line 3206 "parser.tab.c" /* yacc.c:1648 */
++#line 3201 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 103:
+-#line 526 "parser.y" /* yacc.c:1648 */
++#line 524 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENCODE); }
+-#line 3212 "parser.tab.c" /* yacc.c:1648 */
++#line 3207 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 104:
+-#line 527 "parser.y" /* yacc.c:1648 */
++#line 525 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); }
+-#line 3218 "parser.tab.c" /* yacc.c:1648 */
++#line 3213 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 105:
+-#line 528 "parser.y" /* yacc.c:1648 */
++#line 526 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ENTRY, (yyvsp[-1].expr)); }
+-#line 3224 "parser.tab.c" /* yacc.c:1648 */
++#line 3219 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 106:
+-#line 529 "parser.y" /* yacc.c:1648 */
++#line 527 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
+-#line 3230 "parser.tab.c" /* yacc.c:1648 */
++#line 3225 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 107:
+-#line 530 "parser.y" /* yacc.c:1648 */
++#line 528 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_FAULTSTATUS); }
+-#line 3236 "parser.tab.c" /* yacc.c:1648 */
++#line 3231 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 108:
+-#line 531 "parser.y" /* yacc.c:1648 */
++#line 529 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_FORCEALLOCATE); }
+-#line 3242 "parser.tab.c" /* yacc.c:1648 */
++#line 3237 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 109:
+-#line 532 "parser.y" /* yacc.c:1648 */
++#line 530 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_HANDLE); }
+-#line 3248 "parser.tab.c" /* yacc.c:1648 */
++#line 3243 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 110:
+-#line 533 "parser.y" /* yacc.c:1648 */
++#line 531 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); }
+-#line 3254 "parser.tab.c" /* yacc.c:1648 */
++#line 3249 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 111:
+-#line 534 "parser.y" /* yacc.c:1648 */
++#line 532 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); }
+-#line 3260 "parser.tab.c" /* yacc.c:1648 */
++#line 3255 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 112:
+-#line 535 "parser.y" /* yacc.c:1648 */
++#line 533 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); }
+-#line 3266 "parser.tab.c" /* yacc.c:1648 */
++#line 3261 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 113:
+-#line 536 "parser.y" /* yacc.c:1648 */
++#line 534 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); }
+-#line 3272 "parser.tab.c" /* yacc.c:1648 */
++#line 3267 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 114:
+-#line 537 "parser.y" /* yacc.c:1648 */
++#line 535 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); }
+-#line 3278 "parser.tab.c" /* yacc.c:1648 */
++#line 3273 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 115:
+-#line 538 "parser.y" /* yacc.c:1648 */
++#line 536 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_HIDDEN); }
+-#line 3284 "parser.tab.c" /* yacc.c:1648 */
++#line 3279 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 116:
+-#line 539 "parser.y" /* yacc.c:1648 */
++#line 537 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); }
+-#line 3290 "parser.tab.c" /* yacc.c:1648 */
++#line 3285 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 117:
+-#line 540 "parser.y" /* yacc.c:1648 */
++#line 538 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); }
+-#line 3296 "parser.tab.c" /* yacc.c:1648 */
++#line 3291 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 118:
+-#line 541 "parser.y" /* yacc.c:1648 */
++#line 539 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IGNORE); }
+-#line 3302 "parser.tab.c" /* yacc.c:1648 */
++#line 3297 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 119:
+-#line 542 "parser.y" /* yacc.c:1648 */
++#line 540 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); }
+-#line 3308 "parser.tab.c" /* yacc.c:1648 */
++#line 3303 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 120:
+-#line 543 "parser.y" /* yacc.c:1648 */
++#line 541 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); }
+-#line 3314 "parser.tab.c" /* yacc.c:1648 */
++#line 3309 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 121:
+-#line 544 "parser.y" /* yacc.c:1648 */
++#line 542 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].var)); }
+-#line 3320 "parser.tab.c" /* yacc.c:1648 */
++#line 3315 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 122:
+-#line 545 "parser.y" /* yacc.c:1648 */
++#line 543 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_IN); }
+-#line 3326 "parser.tab.c" /* yacc.c:1648 */
++#line 3321 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 123:
+-#line 546 "parser.y" /* yacc.c:1648 */
++#line 544 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_INPUTSYNC); }
+-#line 3332 "parser.tab.c" /* yacc.c:1648 */
++#line 3327 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 124:
+-#line 547 "parser.y" /* yacc.c:1648 */
++#line 545 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); }
+-#line 3338 "parser.tab.c" /* yacc.c:1648 */
++#line 3333 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 125:
+-#line 548 "parser.y" /* yacc.c:1648 */
++#line 546 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_LIBLCID, (yyvsp[-1].expr)); }
+-#line 3344 "parser.tab.c" /* yacc.c:1648 */
++#line 3339 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 126:
+-#line 549 "parser.y" /* yacc.c:1648 */
++#line 547 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PARAMLCID); }
+-#line 3350 "parser.tab.c" /* yacc.c:1648 */
++#line 3345 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 127:
+-#line 550 "parser.y" /* yacc.c:1648 */
++#line 548 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_LICENSED); }
+-#line 3356 "parser.tab.c" /* yacc.c:1648 */
++#line 3351 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 128:
+-#line 551 "parser.y" /* yacc.c:1648 */
++#line 549 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_LOCAL); }
+-#line 3362 "parser.tab.c" /* yacc.c:1648 */
++#line 3357 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 129:
+-#line 552 "parser.y" /* yacc.c:1648 */
++#line 550 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_MAYBE); }
+-#line 3368 "parser.tab.c" /* yacc.c:1648 */
++#line 3363 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 130:
+-#line 553 "parser.y" /* yacc.c:1648 */
++#line 551 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_MESSAGE); }
+-#line 3374 "parser.tab.c" /* yacc.c:1648 */
++#line 3369 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 131:
+-#line 554 "parser.y" /* yacc.c:1648 */
++#line 552 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOCODE); }
+-#line 3380 "parser.tab.c" /* yacc.c:1648 */
++#line 3375 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 132:
+-#line 555 "parser.y" /* yacc.c:1648 */
++#line 553 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); }
+-#line 3386 "parser.tab.c" /* yacc.c:1648 */
++#line 3381 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 133:
+-#line 556 "parser.y" /* yacc.c:1648 */
++#line 554 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONCREATABLE); }
+-#line 3392 "parser.tab.c" /* yacc.c:1648 */
++#line 3387 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 134:
+-#line 557 "parser.y" /* yacc.c:1648 */
++#line 555 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); }
+-#line 3398 "parser.tab.c" /* yacc.c:1648 */
++#line 3393 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 135:
+-#line 558 "parser.y" /* yacc.c:1648 */
++#line 556 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOTIFY); }
+-#line 3404 "parser.tab.c" /* yacc.c:1648 */
++#line 3399 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 136:
+-#line 559 "parser.y" /* yacc.c:1648 */
++#line 557 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_NOTIFYFLAG); }
+-#line 3410 "parser.tab.c" /* yacc.c:1648 */
++#line 3405 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 137:
+-#line 560 "parser.y" /* yacc.c:1648 */
++#line 558 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OBJECT); }
+-#line 3416 "parser.tab.c" /* yacc.c:1648 */
++#line 3411 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 138:
+-#line 561 "parser.y" /* yacc.c:1648 */
++#line 559 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ODL); }
+-#line 3422 "parser.tab.c" /* yacc.c:1648 */
++#line 3417 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 139:
+-#line 562 "parser.y" /* yacc.c:1648 */
++#line 560 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); }
+-#line 3428 "parser.tab.c" /* yacc.c:1648 */
++#line 3423 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 140:
+-#line 563 "parser.y" /* yacc.c:1648 */
++#line 561 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_OPTIMIZE, (yyvsp[-1].str)); }
+-#line 3434 "parser.tab.c" /* yacc.c:1648 */
++#line 3429 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 141:
+-#line 564 "parser.y" /* yacc.c:1648 */
++#line 562 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OPTIONAL); }
+-#line 3440 "parser.tab.c" /* yacc.c:1648 */
++#line 3435 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 142:
+-#line 565 "parser.y" /* yacc.c:1648 */
++#line 563 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_OUT); }
+-#line 3446 "parser.tab.c" /* yacc.c:1648 */
++#line 3441 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 143:
+-#line 566 "parser.y" /* yacc.c:1648 */
++#line 564 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PARTIALIGNORE); }
+-#line 3452 "parser.tab.c" /* yacc.c:1648 */
++#line 3447 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 144:
+-#line 567 "parser.y" /* yacc.c:1648 */
++#line 565 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); }
+-#line 3458 "parser.tab.c" /* yacc.c:1648 */
++#line 3453 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 145:
+-#line 568 "parser.y" /* yacc.c:1648 */
++#line 566 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_PROGID, (yyvsp[-1].str)); }
+-#line 3464 "parser.tab.c" /* yacc.c:1648 */
++#line 3459 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 146:
+-#line 569 "parser.y" /* yacc.c:1648 */
++#line 567 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPGET); }
+-#line 3470 "parser.tab.c" /* yacc.c:1648 */
++#line 3465 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 147:
+-#line 570 "parser.y" /* yacc.c:1648 */
++#line 568 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPPUT); }
+-#line 3476 "parser.tab.c" /* yacc.c:1648 */
++#line 3471 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 148:
+-#line 571 "parser.y" /* yacc.c:1648 */
++#line 569 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROPPUTREF); }
+-#line 3482 "parser.tab.c" /* yacc.c:1648 */
++#line 3477 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 149:
+-#line 572 "parser.y" /* yacc.c:1648 */
++#line 570 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PROXY); }
+-#line 3488 "parser.tab.c" /* yacc.c:1648 */
++#line 3483 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 150:
+-#line 573 "parser.y" /* yacc.c:1648 */
++#line 571 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_PUBLIC); }
+-#line 3494 "parser.tab.c" /* yacc.c:1648 */
++#line 3489 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 151:
+-#line 575 "parser.y" /* yacc.c:1648 */
++#line 573 "parser.y" /* yacc.c:1646 */
+ { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) );
+ list = append_expr( list, (yyvsp[-1].expr) );
+ (yyval.attr) = make_attrp(ATTR_RANGE, list); }
+-#line 3502 "parser.tab.c" /* yacc.c:1648 */
++#line 3497 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 152:
+-#line 578 "parser.y" /* yacc.c:1648 */
++#line 576 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_READONLY); }
+-#line 3508 "parser.tab.c" /* yacc.c:1648 */
++#line 3503 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 153:
+-#line 579 "parser.y" /* yacc.c:1648 */
++#line 577 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_REPRESENTAS, (yyvsp[-1].type)); }
+-#line 3514 "parser.tab.c" /* yacc.c:1648 */
++#line 3509 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 154:
+-#line 580 "parser.y" /* yacc.c:1648 */
++#line 578 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); }
+-#line 3520 "parser.tab.c" /* yacc.c:1648 */
++#line 3515 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 155:
+-#line 581 "parser.y" /* yacc.c:1648 */
++#line 579 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_RESTRICTED); }
+-#line 3526 "parser.tab.c" /* yacc.c:1648 */
++#line 3521 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 156:
+-#line 582 "parser.y" /* yacc.c:1648 */
++#line 580 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_RETVAL); }
+-#line 3532 "parser.tab.c" /* yacc.c:1648 */
++#line 3527 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 157:
+-#line 583 "parser.y" /* yacc.c:1648 */
++#line 581 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); }
+-#line 3538 "parser.tab.c" /* yacc.c:1648 */
++#line 3533 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 158:
+-#line 584 "parser.y" /* yacc.c:1648 */
++#line 582 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_SOURCE); }
+-#line 3544 "parser.tab.c" /* yacc.c:1648 */
++#line 3539 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 159:
+-#line 585 "parser.y" /* yacc.c:1648 */
++#line 583 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); }
+-#line 3550 "parser.tab.c" /* yacc.c:1648 */
++#line 3545 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 160:
+-#line 586 "parser.y" /* yacc.c:1648 */
++#line 584 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_STRING); }
+-#line 3556 "parser.tab.c" /* yacc.c:1648 */
++#line 3551 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 161:
+-#line 587 "parser.y" /* yacc.c:1648 */
++#line 585 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); }
+-#line 3562 "parser.tab.c" /* yacc.c:1648 */
++#line 3557 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 162:
+-#line 588 "parser.y" /* yacc.c:1648 */
++#line 586 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); }
+-#line 3568 "parser.tab.c" /* yacc.c:1648 */
++#line 3563 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 163:
+-#line 589 "parser.y" /* yacc.c:1648 */
++#line 587 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); }
+-#line 3574 "parser.tab.c" /* yacc.c:1648 */
++#line 3569 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 164:
+-#line 590 "parser.y" /* yacc.c:1648 */
++#line 588 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_THREADING, (yyvsp[-1].num)); }
+-#line 3580 "parser.tab.c" /* yacc.c:1648 */
++#line 3575 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 165:
+-#line 591 "parser.y" /* yacc.c:1648 */
++#line 589 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_UIDEFAULT); }
+-#line 3586 "parser.tab.c" /* yacc.c:1648 */
++#line 3581 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 166:
+-#line 592 "parser.y" /* yacc.c:1648 */
++#line 590 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_USESGETLASTERROR); }
+-#line 3592 "parser.tab.c" /* yacc.c:1648 */
++#line 3587 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 167:
+-#line 593 "parser.y" /* yacc.c:1648 */
++#line 591 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_USERMARSHAL, (yyvsp[-1].type)); }
+-#line 3598 "parser.tab.c" /* yacc.c:1648 */
++#line 3593 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 168:
+-#line 594 "parser.y" /* yacc.c:1648 */
++#line 592 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); }
+-#line 3604 "parser.tab.c" /* yacc.c:1648 */
++#line 3599 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 169:
+-#line 595 "parser.y" /* yacc.c:1648 */
++#line 593 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_ASYNCUUID, (yyvsp[-1].uuid)); }
+-#line 3610 "parser.tab.c" /* yacc.c:1648 */
++#line 3605 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 170:
+-#line 596 "parser.y" /* yacc.c:1648 */
++#line 594 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_V1ENUM); }
+-#line 3616 "parser.tab.c" /* yacc.c:1648 */
++#line 3611 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 171:
+-#line 597 "parser.y" /* yacc.c:1648 */
++#line 595 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_VARARG); }
+-#line 3622 "parser.tab.c" /* yacc.c:1648 */
++#line 3617 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 172:
+-#line 598 "parser.y" /* yacc.c:1648 */
++#line 596 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); }
+-#line 3628 "parser.tab.c" /* yacc.c:1648 */
++#line 3623 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 173:
+-#line 599 "parser.y" /* yacc.c:1648 */
++#line 597 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_VIPROGID, (yyvsp[-1].str)); }
+-#line 3634 "parser.tab.c" /* yacc.c:1648 */
++#line 3629 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 174:
+-#line 600 "parser.y" /* yacc.c:1648 */
++#line 598 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); }
+-#line 3640 "parser.tab.c" /* yacc.c:1648 */
++#line 3635 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 175:
+-#line 601 "parser.y" /* yacc.c:1648 */
++#line 599 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); }
+-#line 3646 "parser.tab.c" /* yacc.c:1648 */
++#line 3641 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 177:
+-#line 606 "parser.y" /* yacc.c:1648 */
++#line 604 "parser.y" /* yacc.c:1646 */
+ { if (!is_valid_uuid((yyvsp[0].str)))
+ error_loc("invalid UUID: %s\n", (yyvsp[0].str));
+ (yyval.uuid) = parse_uuid((yyvsp[0].str)); }
+-#line 3654 "parser.tab.c" /* yacc.c:1648 */
++#line 3649 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 178:
+-#line 611 "parser.y" /* yacc.c:1648 */
++#line 609 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__cdecl"); }
+-#line 3660 "parser.tab.c" /* yacc.c:1648 */
++#line 3655 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 179:
+-#line 612 "parser.y" /* yacc.c:1648 */
++#line 610 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__fastcall"); }
+-#line 3666 "parser.tab.c" /* yacc.c:1648 */
++#line 3661 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 180:
+-#line 613 "parser.y" /* yacc.c:1648 */
++#line 611 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__pascal"); }
+-#line 3672 "parser.tab.c" /* yacc.c:1648 */
++#line 3667 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 181:
+-#line 614 "parser.y" /* yacc.c:1648 */
++#line 612 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = xstrdup("__stdcall"); }
+-#line 3678 "parser.tab.c" /* yacc.c:1648 */
++#line 3673 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 182:
+-#line 617 "parser.y" /* yacc.c:1648 */
++#line 615 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 3684 "parser.tab.c" /* yacc.c:1648 */
++#line 3679 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 183:
+-#line 618 "parser.y" /* yacc.c:1648 */
++#line 616 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
+-#line 3690 "parser.tab.c" /* yacc.c:1648 */
++#line 3685 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 184:
+-#line 621 "parser.y" /* yacc.c:1648 */
++#line 619 "parser.y" /* yacc.c:1646 */
+ { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) ));
+ (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
+ (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
+ }
+-#line 3699 "parser.tab.c" /* yacc.c:1648 */
++#line 3694 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 185:
+-#line 625 "parser.y" /* yacc.c:1648 */
++#line 623 "parser.y" /* yacc.c:1646 */
+ { attr_t *a = make_attr(ATTR_DEFAULT);
+ (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
+ (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
+ }
+-#line 3708 "parser.tab.c" /* yacc.c:1648 */
++#line 3703 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 186:
+-#line 631 "parser.y" /* yacc.c:1648 */
++#line 629 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 3714 "parser.tab.c" /* yacc.c:1648 */
++#line 3709 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 187:
+-#line 632 "parser.y" /* yacc.c:1648 */
++#line 630 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = (yyvsp[-1].var_list); }
+-#line 3720 "parser.tab.c" /* yacc.c:1648 */
++#line 3715 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 189:
+-#line 636 "parser.y" /* yacc.c:1648 */
++#line 634 "parser.y" /* yacc.c:1646 */
+ { if (!(yyvsp[0].var)->eval)
+ (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
+ (yyval.var_list) = append_var( NULL, (yyvsp[0].var) );
+ }
+-#line 3729 "parser.tab.c" /* yacc.c:1648 */
++#line 3724 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 190:
+-#line 640 "parser.y" /* yacc.c:1648 */
++#line 638 "parser.y" /* yacc.c:1646 */
+ { if (!(yyvsp[0].var)->eval)
+ {
+ var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry );
+@@ -3740,656 +3735,656 @@ yyreduce:
+ }
+ (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) );
+ }
+-#line 3744 "parser.tab.c" /* yacc.c:1648 */
++#line 3739 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 191:
+-#line 652 "parser.y" /* yacc.c:1648 */
++#line 650 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = reg_const((yyvsp[-2].var));
+ (yyval.var)->eval = (yyvsp[0].expr);
+- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
++ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+-#line 3753 "parser.tab.c" /* yacc.c:1648 */
++#line 3748 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 192:
+-#line 656 "parser.y" /* yacc.c:1648 */
++#line 654 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = reg_const((yyvsp[0].var));
+- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
++ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
+ }
+-#line 3761 "parser.tab.c" /* yacc.c:1648 */
++#line 3756 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 193:
+-#line 661 "parser.y" /* yacc.c:1648 */
++#line 659 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
+-#line 3767 "parser.tab.c" /* yacc.c:1648 */
++#line 3762 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 194:
+-#line 664 "parser.y" /* yacc.c:1648 */
++#line 662 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
+-#line 3773 "parser.tab.c" /* yacc.c:1648 */
++#line 3768 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 195:
+-#line 665 "parser.y" /* yacc.c:1648 */
++#line 663 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
+-#line 3779 "parser.tab.c" /* yacc.c:1648 */
++#line 3774 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 196:
+-#line 668 "parser.y" /* yacc.c:1648 */
++#line 666 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr(EXPR_VOID); }
+-#line 3785 "parser.tab.c" /* yacc.c:1648 */
++#line 3780 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 198:
+-#line 672 "parser.y" /* yacc.c:1648 */
++#line 670 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); }
+-#line 3791 "parser.tab.c" /* yacc.c:1648 */
++#line 3786 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 199:
+-#line 673 "parser.y" /* yacc.c:1648 */
++#line 671 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); }
+-#line 3797 "parser.tab.c" /* yacc.c:1648 */
++#line 3792 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 200:
+-#line 674 "parser.y" /* yacc.c:1648 */
++#line 672 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); }
+-#line 3803 "parser.tab.c" /* yacc.c:1648 */
++#line 3798 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 201:
+-#line 675 "parser.y" /* yacc.c:1648 */
++#line 673 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); }
+-#line 3809 "parser.tab.c" /* yacc.c:1648 */
++#line 3804 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 202:
+-#line 676 "parser.y" /* yacc.c:1648 */
++#line 674 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_NUM, 0); }
+-#line 3815 "parser.tab.c" /* yacc.c:1648 */
++#line 3810 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 203:
+-#line 677 "parser.y" /* yacc.c:1648 */
++#line 675 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); }
+-#line 3821 "parser.tab.c" /* yacc.c:1648 */
++#line 3816 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 204:
+-#line 678 "parser.y" /* yacc.c:1648 */
++#line 676 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_STRLIT, (yyvsp[0].str)); }
+-#line 3827 "parser.tab.c" /* yacc.c:1648 */
++#line 3822 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 205:
+-#line 679 "parser.y" /* yacc.c:1648 */
++#line 677 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_WSTRLIT, (yyvsp[0].str)); }
+-#line 3833 "parser.tab.c" /* yacc.c:1648 */
++#line 3828 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 206:
+-#line 680 "parser.y" /* yacc.c:1648 */
++#line 678 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_CHARCONST, (yyvsp[0].str)); }
+-#line 3839 "parser.tab.c" /* yacc.c:1648 */
++#line 3834 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 207:
+-#line 681 "parser.y" /* yacc.c:1648 */
++#line 679 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); }
+-#line 3845 "parser.tab.c" /* yacc.c:1648 */
++#line 3840 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 208:
+-#line 682 "parser.y" /* yacc.c:1648 */
++#line 680 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3851 "parser.tab.c" /* yacc.c:1648 */
++#line 3846 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 209:
+-#line 683 "parser.y" /* yacc.c:1648 */
++#line 681 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LOGOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3857 "parser.tab.c" /* yacc.c:1648 */
++#line 3852 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 210:
+-#line 684 "parser.y" /* yacc.c:1648 */
++#line 682 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LOGAND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3863 "parser.tab.c" /* yacc.c:1648 */
++#line 3858 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 211:
+-#line 685 "parser.y" /* yacc.c:1648 */
++#line 683 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3869 "parser.tab.c" /* yacc.c:1648 */
++#line 3864 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 212:
+-#line 686 "parser.y" /* yacc.c:1648 */
++#line 684 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_XOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3875 "parser.tab.c" /* yacc.c:1648 */
++#line 3870 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 213:
+-#line 687 "parser.y" /* yacc.c:1648 */
++#line 685 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3881 "parser.tab.c" /* yacc.c:1648 */
++#line 3876 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 214:
+-#line 688 "parser.y" /* yacc.c:1648 */
++#line 686 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_EQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3887 "parser.tab.c" /* yacc.c:1648 */
++#line 3882 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 215:
+-#line 689 "parser.y" /* yacc.c:1648 */
++#line 687 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_INEQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3893 "parser.tab.c" /* yacc.c:1648 */
++#line 3888 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 216:
+-#line 690 "parser.y" /* yacc.c:1648 */
++#line 688 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_GTR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3899 "parser.tab.c" /* yacc.c:1648 */
++#line 3894 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 217:
+-#line 691 "parser.y" /* yacc.c:1648 */
++#line 689 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LESS, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3905 "parser.tab.c" /* yacc.c:1648 */
++#line 3900 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 218:
+-#line 692 "parser.y" /* yacc.c:1648 */
++#line 690 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_GTREQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3911 "parser.tab.c" /* yacc.c:1648 */
++#line 3906 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 219:
+-#line 693 "parser.y" /* yacc.c:1648 */
++#line 691 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_LESSEQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3917 "parser.tab.c" /* yacc.c:1648 */
++#line 3912 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 220:
+-#line 694 "parser.y" /* yacc.c:1648 */
++#line 692 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3923 "parser.tab.c" /* yacc.c:1648 */
++#line 3918 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 221:
+-#line 695 "parser.y" /* yacc.c:1648 */
++#line 693 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3929 "parser.tab.c" /* yacc.c:1648 */
++#line 3924 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 222:
+-#line 696 "parser.y" /* yacc.c:1648 */
++#line 694 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3935 "parser.tab.c" /* yacc.c:1648 */
++#line 3930 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 223:
+-#line 697 "parser.y" /* yacc.c:1648 */
++#line 695 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3941 "parser.tab.c" /* yacc.c:1648 */
++#line 3936 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 224:
+-#line 698 "parser.y" /* yacc.c:1648 */
++#line 696 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MOD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3947 "parser.tab.c" /* yacc.c:1648 */
++#line 3942 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 225:
+-#line 699 "parser.y" /* yacc.c:1648 */
++#line 697 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3953 "parser.tab.c" /* yacc.c:1648 */
++#line 3948 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 226:
+-#line 700 "parser.y" /* yacc.c:1648 */
++#line 698 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); }
+-#line 3959 "parser.tab.c" /* yacc.c:1648 */
++#line 3954 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 227:
+-#line 701 "parser.y" /* yacc.c:1648 */
++#line 699 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_LOGNOT, (yyvsp[0].expr)); }
+-#line 3965 "parser.tab.c" /* yacc.c:1648 */
++#line 3960 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 228:
+-#line 702 "parser.y" /* yacc.c:1648 */
++#line 700 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); }
+-#line 3971 "parser.tab.c" /* yacc.c:1648 */
++#line 3966 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 229:
+-#line 703 "parser.y" /* yacc.c:1648 */
++#line 701 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_POS, (yyvsp[0].expr)); }
+-#line 3977 "parser.tab.c" /* yacc.c:1648 */
++#line 3972 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 230:
+-#line 704 "parser.y" /* yacc.c:1648 */
++#line 702 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); }
+-#line 3983 "parser.tab.c" /* yacc.c:1648 */
++#line 3978 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 231:
+-#line 705 "parser.y" /* yacc.c:1648 */
++#line 703 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); }
+-#line 3989 "parser.tab.c" /* yacc.c:1648 */
++#line 3984 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 232:
+-#line 706 "parser.y" /* yacc.c:1648 */
++#line 704 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); }
+-#line 3995 "parser.tab.c" /* yacc.c:1648 */
++#line 3990 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 233:
+-#line 707 "parser.y" /* yacc.c:1648 */
++#line 705 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, (yyvsp[-2].expr)), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
+-#line 4001 "parser.tab.c" /* yacc.c:1648 */
++#line 3996 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 234:
+-#line 708 "parser.y" /* yacc.c:1648 */
++#line 706 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_MEMBER, (yyvsp[-2].expr), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
+-#line 4007 "parser.tab.c" /* yacc.c:1648 */
++#line 4002 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 235:
+-#line 710 "parser.y" /* yacc.c:1648 */
++#line 708 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprt(EXPR_CAST, declare_var(NULL, (yyvsp[-3].declspec), (yyvsp[-2].declarator), 0), (yyvsp[0].expr)); free((yyvsp[-3].declspec)); free((yyvsp[-2].declarator)); }
+-#line 4013 "parser.tab.c" /* yacc.c:1648 */
++#line 4008 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 236:
+-#line 712 "parser.y" /* yacc.c:1648 */
++#line 710 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_exprt(EXPR_SIZEOF, declare_var(NULL, (yyvsp[-2].declspec), (yyvsp[-1].declarator), 0), NULL); free((yyvsp[-2].declspec)); free((yyvsp[-1].declarator)); }
+-#line 4019 "parser.tab.c" /* yacc.c:1648 */
++#line 4014 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 237:
+-#line 713 "parser.y" /* yacc.c:1648 */
++#line 711 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = make_expr2(EXPR_ARRAY, (yyvsp[-3].expr), (yyvsp[-1].expr)); }
+-#line 4025 "parser.tab.c" /* yacc.c:1648 */
++#line 4020 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 238:
+-#line 714 "parser.y" /* yacc.c:1648 */
++#line 712 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[-1].expr); }
+-#line 4031 "parser.tab.c" /* yacc.c:1648 */
++#line 4026 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 239:
+-#line 717 "parser.y" /* yacc.c:1648 */
++#line 715 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
+-#line 4037 "parser.tab.c" /* yacc.c:1648 */
++#line 4032 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 240:
+-#line 718 "parser.y" /* yacc.c:1648 */
++#line 716 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
+-#line 4043 "parser.tab.c" /* yacc.c:1648 */
++#line 4038 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 241:
+-#line 721 "parser.y" /* yacc.c:1648 */
++#line 719 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr);
+ if (!(yyval.expr)->is_const)
+ error_loc("expression is not an integer constant\n");
+ }
+-#line 4052 "parser.tab.c" /* yacc.c:1648 */
++#line 4047 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 242:
+-#line 727 "parser.y" /* yacc.c:1648 */
++#line 725 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr);
+ if (!(yyval.expr)->is_const && (yyval.expr)->type != EXPR_STRLIT && (yyval.expr)->type != EXPR_WSTRLIT)
+ error_loc("expression is not constant\n");
+ }
+-#line 4061 "parser.tab.c" /* yacc.c:1648 */
++#line 4056 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 243:
+-#line 733 "parser.y" /* yacc.c:1648 */
++#line 731 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4067 "parser.tab.c" /* yacc.c:1648 */
++#line 4062 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 244:
+-#line 734 "parser.y" /* yacc.c:1648 */
++#line 732 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var_list((yyvsp[-1].var_list), (yyvsp[0].var_list)); }
+-#line 4073 "parser.tab.c" /* yacc.c:1648 */
++#line 4068 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 245:
+-#line 738 "parser.y" /* yacc.c:1648 */
++#line 736 "parser.y" /* yacc.c:1646 */
+ { const char *first = LIST_ENTRY(list_head((yyvsp[-1].declarator_list)), declarator_t, entry)->var->name;
+ check_field_attrs(first, (yyvsp[-3].attr_list));
+ (yyval.var_list) = set_var_types((yyvsp[-3].attr_list), (yyvsp[-2].declspec), (yyvsp[-1].declarator_list));
+ }
+-#line 4082 "parser.tab.c" /* yacc.c:1648 */
++#line 4077 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 246:
+-#line 742 "parser.y" /* yacc.c:1648 */
++#line 740 "parser.y" /* yacc.c:1646 */
+ { var_t *v = make_var(NULL);
+- v->type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
++ v->declspec.type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
+ (yyval.var_list) = append_var(NULL, v);
+ }
+-#line 4091 "parser.tab.c" /* yacc.c:1648 */
++#line 4086 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 247:
+-#line 749 "parser.y" /* yacc.c:1648 */
++#line 747 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[-1].var); }
+-#line 4097 "parser.tab.c" /* yacc.c:1648 */
++#line 4092 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 248:
+-#line 750 "parser.y" /* yacc.c:1648 */
++#line 748 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); }
+-#line 4103 "parser.tab.c" /* yacc.c:1648 */
++#line 4098 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 249:
+-#line 753 "parser.y" /* yacc.c:1648 */
++#line 751 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4109 "parser.tab.c" /* yacc.c:1648 */
++#line 4104 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 250:
+-#line 754 "parser.y" /* yacc.c:1648 */
++#line 752 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
+-#line 4115 "parser.tab.c" /* yacc.c:1648 */
++#line 4110 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 251:
+-#line 758 "parser.y" /* yacc.c:1648 */
++#line 756 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[-1].var); }
+-#line 4121 "parser.tab.c" /* yacc.c:1648 */
++#line 4116 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 252:
+-#line 759 "parser.y" /* yacc.c:1648 */
++#line 757 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = NULL; }
+-#line 4127 "parser.tab.c" /* yacc.c:1648 */
++#line 4122 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 253:
+-#line 762 "parser.y" /* yacc.c:1648 */
++#line 760 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var(check_field_attrs((yyvsp[0].declarator)->var->name, (yyvsp[-2].attr_list)),
+ (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4136 "parser.tab.c" /* yacc.c:1648 */
++#line 4131 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 254:
+-#line 766 "parser.y" /* yacc.c:1648 */
++#line 764 "parser.y" /* yacc.c:1646 */
+ { var_t *v = make_var(NULL);
+- v->type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
++ v->declspec.type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
+ (yyval.var) = v;
+ }
+-#line 4145 "parser.tab.c" /* yacc.c:1648 */
++#line 4140 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 255:
+-#line 772 "parser.y" /* yacc.c:1648 */
++#line 770 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = (yyvsp[0].var);
+- if (type_get_type((yyval.var)->type) != TYPE_FUNCTION)
++ if (type_get_type((yyval.var)->declspec.type) != TYPE_FUNCTION)
+ error_loc("only methods may be declared inside the methods section of a dispinterface\n");
+ check_function_attrs((yyval.var)->name, (yyval.var)->attrs);
+ }
+-#line 4155 "parser.tab.c" /* yacc.c:1648 */
++#line 4150 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 256:
+-#line 781 "parser.y" /* yacc.c:1648 */
++#line 779 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4163 "parser.tab.c" /* yacc.c:1648 */
++#line 4158 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 257:
+-#line 784 "parser.y" /* yacc.c:1648 */
++#line 782 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+ free((yyvsp[0].declarator));
+ }
+-#line 4171 "parser.tab.c" /* yacc.c:1648 */
++#line 4166 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 258:
+-#line 789 "parser.y" /* yacc.c:1648 */
++#line 787 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = NULL; }
+-#line 4177 "parser.tab.c" /* yacc.c:1648 */
++#line 4172 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 260:
+-#line 793 "parser.y" /* yacc.c:1648 */
++#line 791 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = NULL; }
+-#line 4183 "parser.tab.c" /* yacc.c:1648 */
++#line 4178 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 261:
+-#line 794 "parser.y" /* yacc.c:1648 */
++#line 792 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4189 "parser.tab.c" /* yacc.c:1648 */
++#line 4184 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 262:
+-#line 795 "parser.y" /* yacc.c:1648 */
++#line 793 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4195 "parser.tab.c" /* yacc.c:1648 */
++#line 4190 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 263:
+-#line 798 "parser.y" /* yacc.c:1648 */
++#line 796 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var((yyvsp[0].str)); }
+-#line 4201 "parser.tab.c" /* yacc.c:1648 */
++#line 4196 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 264:
+-#line 800 "parser.y" /* yacc.c:1648 */
++#line 798 "parser.y" /* yacc.c:1646 */
+ { (yyval.var) = make_var((yyvsp[0].str)); }
+-#line 4207 "parser.tab.c" /* yacc.c:1648 */
++#line 4202 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 265:
+-#line 803 "parser.y" /* yacc.c:1648 */
++#line 801 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4213 "parser.tab.c" /* yacc.c:1648 */
++#line 4208 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 266:
+-#line 804 "parser.y" /* yacc.c:1648 */
++#line 802 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4219 "parser.tab.c" /* yacc.c:1648 */
++#line 4214 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 268:
+-#line 806 "parser.y" /* yacc.c:1648 */
++#line 804 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), -1); }
+-#line 4225 "parser.tab.c" /* yacc.c:1648 */
++#line 4220 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 269:
+-#line 807 "parser.y" /* yacc.c:1648 */
++#line 805 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), 1); }
+-#line 4231 "parser.tab.c" /* yacc.c:1648 */
++#line 4226 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 270:
+-#line 808 "parser.y" /* yacc.c:1648 */
++#line 806 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT, 1); }
+-#line 4237 "parser.tab.c" /* yacc.c:1648 */
++#line 4232 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 271:
+-#line 809 "parser.y" /* yacc.c:1648 */
++#line 807 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4243 "parser.tab.c" /* yacc.c:1648 */
++#line 4238 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 272:
+-#line 810 "parser.y" /* yacc.c:1648 */
++#line 808 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4249 "parser.tab.c" /* yacc.c:1648 */
++#line 4244 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 273:
+-#line 811 "parser.y" /* yacc.c:1648 */
++#line 809 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4255 "parser.tab.c" /* yacc.c:1648 */
++#line 4250 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 274:
+-#line 812 "parser.y" /* yacc.c:1648 */
++#line 810 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4261 "parser.tab.c" /* yacc.c:1648 */
++#line 4256 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 275:
+-#line 813 "parser.y" /* yacc.c:1648 */
++#line 811 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4267 "parser.tab.c" /* yacc.c:1648 */
++#line 4262 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 278:
+-#line 820 "parser.y" /* yacc.c:1648 */
++#line 818 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT, 0); }
+-#line 4273 "parser.tab.c" /* yacc.c:1648 */
++#line 4268 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 279:
+-#line 821 "parser.y" /* yacc.c:1648 */
++#line 819 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT16, 0); }
+-#line 4279 "parser.tab.c" /* yacc.c:1648 */
++#line 4274 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 280:
+-#line 822 "parser.y" /* yacc.c:1648 */
++#line 820 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT8, 0); }
+-#line 4285 "parser.tab.c" /* yacc.c:1648 */
++#line 4280 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 281:
+-#line 823 "parser.y" /* yacc.c:1648 */
++#line 821 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_LONG, 0); }
+-#line 4291 "parser.tab.c" /* yacc.c:1648 */
++#line 4286 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 282:
+-#line 824 "parser.y" /* yacc.c:1648 */
++#line 822 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_HYPER, 0); }
+-#line 4297 "parser.tab.c" /* yacc.c:1648 */
++#line 4292 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 283:
+-#line 825 "parser.y" /* yacc.c:1648 */
++#line 823 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT64, 0); }
+-#line 4303 "parser.tab.c" /* yacc.c:1648 */
++#line 4298 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 284:
+-#line 826 "parser.y" /* yacc.c:1648 */
++#line 824 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_CHAR, 0); }
+-#line 4309 "parser.tab.c" /* yacc.c:1648 */
++#line 4304 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 285:
+-#line 827 "parser.y" /* yacc.c:1648 */
++#line 825 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT32, 0); }
+-#line 4315 "parser.tab.c" /* yacc.c:1648 */
++#line 4310 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 286:
+-#line 828 "parser.y" /* yacc.c:1648 */
++#line 826 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_int(TYPE_BASIC_INT3264, 0); }
+-#line 4321 "parser.tab.c" /* yacc.c:1648 */
++#line 4316 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 287:
+-#line 831 "parser.y" /* yacc.c:1648 */
++#line 829 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_coclass((yyvsp[0].str)); }
+-#line 4327 "parser.tab.c" /* yacc.c:1648 */
++#line 4322 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 288:
+-#line 832 "parser.y" /* yacc.c:1648 */
++#line 830 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type((yyvsp[0].str), NULL, 0);
+ if (type_get_type_detect_alias((yyval.type)) != TYPE_COCLASS)
+ error_loc("%s was not declared a coclass at %s:%d\n",
+ (yyvsp[0].str), (yyval.type)->loc_info.input_name,
+ (yyval.type)->loc_info.line_number);
+ }
+-#line 4338 "parser.tab.c" /* yacc.c:1648 */
++#line 4333 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 289:
+-#line 840 "parser.y" /* yacc.c:1648 */
++#line 838 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type);
+ check_def((yyval.type));
+ (yyval.type)->attrs = check_coclass_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ }
+-#line 4347 "parser.tab.c" /* yacc.c:1648 */
++#line 4342 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 290:
+-#line 847 "parser.y" /* yacc.c:1648 */
++#line 845 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_coclass_define((yyvsp[-4].type), (yyvsp[-2].ifref_list)); }
+-#line 4353 "parser.tab.c" /* yacc.c:1648 */
++#line 4348 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 291:
+-#line 850 "parser.y" /* yacc.c:1648 */
++#line 848 "parser.y" /* yacc.c:1646 */
+ { (yyval.str) = (yyvsp[0].str); }
+-#line 4359 "parser.tab.c" /* yacc.c:1648 */
++#line 4354 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 292:
+-#line 853 "parser.y" /* yacc.c:1648 */
++#line 851 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref_list) = NULL; }
+-#line 4365 "parser.tab.c" /* yacc.c:1648 */
++#line 4360 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 293:
+-#line 854 "parser.y" /* yacc.c:1648 */
++#line 852 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); }
+-#line 4371 "parser.tab.c" /* yacc.c:1648 */
++#line 4366 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 294:
+-#line 858 "parser.y" /* yacc.c:1648 */
++#line 856 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); }
+-#line 4377 "parser.tab.c" /* yacc.c:1648 */
++#line 4372 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 295:
+-#line 861 "parser.y" /* yacc.c:1648 */
++#line 859 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4383 "parser.tab.c" /* yacc.c:1648 */
++#line 4378 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 296:
+-#line 862 "parser.y" /* yacc.c:1648 */
++#line 860 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4389 "parser.tab.c" /* yacc.c:1648 */
++#line 4384 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 297:
+-#line 865 "parser.y" /* yacc.c:1648 */
++#line 863 "parser.y" /* yacc.c:1646 */
+ { attr_t *attrs;
+ (yyval.type) = (yyvsp[0].type);
+ check_def((yyval.type));
+@@ -4397,75 +4392,75 @@ yyreduce:
+ (yyval.type)->attrs = append_attr( check_dispiface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list)), attrs );
+ (yyval.type)->defined = TRUE;
+ }
+-#line 4401 "parser.tab.c" /* yacc.c:1648 */
++#line 4396 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 298:
+-#line 874 "parser.y" /* yacc.c:1648 */
++#line 872 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4407 "parser.tab.c" /* yacc.c:1648 */
++#line 4402 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 299:
+-#line 875 "parser.y" /* yacc.c:1648 */
++#line 873 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
+-#line 4413 "parser.tab.c" /* yacc.c:1648 */
++#line 4408 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 300:
+-#line 878 "parser.y" /* yacc.c:1648 */
++#line 876 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = NULL; }
+-#line 4419 "parser.tab.c" /* yacc.c:1648 */
++#line 4414 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 301:
+-#line 879 "parser.y" /* yacc.c:1648 */
++#line 877 "parser.y" /* yacc.c:1646 */
+ { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
+-#line 4425 "parser.tab.c" /* yacc.c:1648 */
++#line 4420 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 302:
+-#line 885 "parser.y" /* yacc.c:1648 */
++#line 883 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_dispinterface_define((yyval.type), (yyvsp[-2].var_list), (yyvsp[-1].var_list));
+ }
+-#line 4433 "parser.tab.c" /* yacc.c:1648 */
++#line 4428 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 303:
+-#line 889 "parser.y" /* yacc.c:1648 */
++#line 887 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_dispinterface_define_from_iface((yyval.type), (yyvsp[-2].type));
+ }
+-#line 4441 "parser.tab.c" /* yacc.c:1648 */
++#line 4436 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 304:
+-#line 894 "parser.y" /* yacc.c:1648 */
++#line 892 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = NULL; }
+-#line 4447 "parser.tab.c" /* yacc.c:1648 */
++#line 4442 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 305:
+-#line 895 "parser.y" /* yacc.c:1648 */
++#line 893 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error2((yyvsp[0].str), 0); }
+-#line 4453 "parser.tab.c" /* yacc.c:1648 */
++#line 4448 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 306:
+-#line 898 "parser.y" /* yacc.c:1648 */
++#line 896 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4459 "parser.tab.c" /* yacc.c:1648 */
++#line 4454 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 307:
+-#line 899 "parser.y" /* yacc.c:1648 */
++#line 897 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
+-#line 4465 "parser.tab.c" /* yacc.c:1648 */
++#line 4460 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 308:
+-#line 902 "parser.y" /* yacc.c:1648 */
++#line 900 "parser.y" /* yacc.c:1646 */
+ { (yyval.ifinfo).interface = (yyvsp[0].type);
+ (yyval.ifinfo).old_pointer_default = pointer_default;
+ if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT))
+@@ -4474,11 +4469,11 @@ yyreduce:
+ (yyvsp[0].type)->attrs = check_iface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ (yyvsp[0].type)->defined = TRUE;
+ }
+-#line 4478 "parser.tab.c" /* yacc.c:1648 */
++#line 4473 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 309:
+-#line 913 "parser.y" /* yacc.c:1648 */
++#line 911 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-5].ifinfo).interface;
+ if((yyval.type) == (yyvsp[-4].type))
+ error_loc("Interface can't inherit from itself\n");
+@@ -4486,594 +4481,594 @@ yyreduce:
+ check_async_uuid((yyval.type));
+ pointer_default = (yyvsp[-5].ifinfo).old_pointer_default;
+ }
+-#line 4490 "parser.tab.c" /* yacc.c:1648 */
++#line 4485 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 310:
+-#line 924 "parser.y" /* yacc.c:1648 */
++#line 922 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-7].ifinfo).interface;
+ type_interface_define((yyval.type), find_type_or_error2((yyvsp[-5].str), 0), (yyvsp[-2].stmt_list));
+ pointer_default = (yyvsp[-7].ifinfo).old_pointer_default;
+ }
+-#line 4499 "parser.tab.c" /* yacc.c:1648 */
++#line 4494 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 311:
+-#line 928 "parser.y" /* yacc.c:1648 */
++#line 926 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4505 "parser.tab.c" /* yacc.c:1648 */
++#line 4500 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 312:
+-#line 932 "parser.y" /* yacc.c:1648 */
++#line 930 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4511 "parser.tab.c" /* yacc.c:1648 */
++#line 4506 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 313:
+-#line 933 "parser.y" /* yacc.c:1648 */
++#line 931 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-1].type); }
+-#line 4517 "parser.tab.c" /* yacc.c:1648 */
++#line 4512 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 314:
+-#line 936 "parser.y" /* yacc.c:1648 */
++#line 934 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_module((yyvsp[0].str)); }
+-#line 4523 "parser.tab.c" /* yacc.c:1648 */
++#line 4518 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 315:
+-#line 937 "parser.y" /* yacc.c:1648 */
++#line 935 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_module((yyvsp[0].str)); }
+-#line 4529 "parser.tab.c" /* yacc.c:1648 */
++#line 4524 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 316:
+-#line 940 "parser.y" /* yacc.c:1648 */
++#line 938 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type);
+ (yyval.type)->attrs = check_module_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
+ }
+-#line 4537 "parser.tab.c" /* yacc.c:1648 */
++#line 4532 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 317:
+-#line 946 "parser.y" /* yacc.c:1648 */
++#line 944 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[-4].type);
+ type_module_define((yyval.type), (yyvsp[-2].stmt_list));
+ }
+-#line 4545 "parser.tab.c" /* yacc.c:1648 */
++#line 4540 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 318:
+-#line 952 "parser.y" /* yacc.c:1648 */
++#line 950 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_EXTERN; }
+-#line 4551 "parser.tab.c" /* yacc.c:1648 */
++#line 4546 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 319:
+-#line 953 "parser.y" /* yacc.c:1648 */
++#line 951 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_STATIC; }
+-#line 4557 "parser.tab.c" /* yacc.c:1648 */
++#line 4552 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 320:
+-#line 954 "parser.y" /* yacc.c:1648 */
++#line 952 "parser.y" /* yacc.c:1646 */
+ { (yyval.stgclass) = STG_REGISTER; }
+-#line 4563 "parser.tab.c" /* yacc.c:1648 */
++#line 4558 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 321:
+-#line 958 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr) = make_attr(ATTR_INLINE); }
+-#line 4569 "parser.tab.c" /* yacc.c:1648 */
++#line 956 "parser.y" /* yacc.c:1646 */
++ { (yyval.funcspecifier) = FUNCTION_SPECIFIER_INLINE; }
++#line 4564 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 322:
+-#line 962 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr) = make_attr(ATTR_CONST); }
+-#line 4575 "parser.tab.c" /* yacc.c:1648 */
++#line 960 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = TYPE_QUALIFIER_CONST; }
++#line 4570 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 323:
+-#line 965 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr_list) = NULL; }
+-#line 4581 "parser.tab.c" /* yacc.c:1648 */
++#line 963 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = TYPE_QUALIFIER_NONE; }
++#line 4576 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 324:
+-#line 966 "parser.y" /* yacc.c:1648 */
+- { (yyval.attr_list) = append_attr((yyvsp[-1].attr_list), (yyvsp[0].attr)); }
+-#line 4587 "parser.tab.c" /* yacc.c:1648 */
++#line 964 "parser.y" /* yacc.c:1646 */
++ { (yyval.typequalifier) = (yyvsp[-1].typequalifier) | (yyvsp[0].typequalifier); }
++#line 4582 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 325:
+-#line 969 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, NULL, STG_NONE); }
+-#line 4593 "parser.tab.c" /* yacc.c:1648 */
++#line 967 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4588 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 326:
+-#line 971 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), NULL, STG_NONE); }
+-#line 4599 "parser.tab.c" /* yacc.c:1648 */
++#line 969 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4594 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 327:
+-#line 974 "parser.y" /* yacc.c:1648 */
++#line 972 "parser.y" /* yacc.c:1646 */
+ { (yyval.declspec) = NULL; }
+-#line 4605 "parser.tab.c" /* yacc.c:1648 */
++#line 4600 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 329:
+-#line 979 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
+-#line 4611 "parser.tab.c" /* yacc.c:1648 */
++#line 977 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, (yyvsp[-1].typequalifier), FUNCTION_SPECIFIER_NONE); }
++#line 4606 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 330:
+-#line 980 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
+-#line 4617 "parser.tab.c" /* yacc.c:1648 */
++#line 978 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, (yyvsp[-1].funcspecifier)); }
++#line 4612 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 331:
+-#line 981 "parser.y" /* yacc.c:1648 */
+- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, NULL, (yyvsp[-1].stgclass)); }
+-#line 4623 "parser.tab.c" /* yacc.c:1648 */
++#line 979 "parser.y" /* yacc.c:1646 */
++ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].stgclass), TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
++#line 4618 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 332:
+-#line 986 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4629 "parser.tab.c" /* yacc.c:1648 */
++#line 984 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4624 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 333:
+-#line 987 "parser.y" /* yacc.c:1648 */
++#line 985 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4636 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4631 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 335:
+-#line 993 "parser.y" /* yacc.c:1648 */
++#line 991 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
+-#line 4642 "parser.tab.c" /* yacc.c:1648 */
++#line 4637 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 336:
+-#line 994 "parser.y" /* yacc.c:1648 */
++#line 992 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4648 "parser.tab.c" /* yacc.c:1648 */
++#line 4643 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 337:
+-#line 995 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4654 "parser.tab.c" /* yacc.c:1648 */
++#line 993 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4649 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 338:
+-#line 996 "parser.y" /* yacc.c:1648 */
++#line 994 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4663 "parser.tab.c" /* yacc.c:1648 */
++#line 4658 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 339:
+-#line 1005 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4669 "parser.tab.c" /* yacc.c:1648 */
++#line 1003 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4664 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 340:
+-#line 1006 "parser.y" /* yacc.c:1648 */
++#line 1004 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4676 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4671 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 342:
+-#line 1014 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4682 "parser.tab.c" /* yacc.c:1648 */
++#line 1012 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4677 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 343:
+-#line 1015 "parser.y" /* yacc.c:1648 */
++#line 1013 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
+- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4689 "parser.tab.c" /* yacc.c:1648 */
++ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4684 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 344:
+-#line 1020 "parser.y" /* yacc.c:1648 */
++#line 1018 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL); }
+-#line 4695 "parser.tab.c" /* yacc.c:1648 */
++#line 4690 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 346:
+-#line 1026 "parser.y" /* yacc.c:1648 */
++#line 1024 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4701 "parser.tab.c" /* yacc.c:1648 */
++#line 4696 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 347:
+-#line 1027 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4707 "parser.tab.c" /* yacc.c:1648 */
++#line 1025 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4702 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 348:
+-#line 1028 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4713 "parser.tab.c" /* yacc.c:1648 */
++#line 1026 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4708 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 349:
+-#line 1030 "parser.y" /* yacc.c:1648 */
++#line 1028 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4722 "parser.tab.c" /* yacc.c:1648 */
++#line 4717 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 350:
+-#line 1035 "parser.y" /* yacc.c:1648 */
++#line 1033 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4731 "parser.tab.c" /* yacc.c:1648 */
++#line 4726 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 351:
+-#line 1044 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4737 "parser.tab.c" /* yacc.c:1648 */
++#line 1042 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4732 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 352:
+-#line 1045 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4743 "parser.tab.c" /* yacc.c:1648 */
++#line 1043 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4738 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 354:
+-#line 1052 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
+-#line 4749 "parser.tab.c" /* yacc.c:1648 */
++#line 1050 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
++#line 4744 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 355:
+-#line 1053 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
+-#line 4755 "parser.tab.c" /* yacc.c:1648 */
++#line 1051 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
++#line 4750 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 356:
+-#line 1057 "parser.y" /* yacc.c:1648 */
++#line 1055 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL); }
+-#line 4761 "parser.tab.c" /* yacc.c:1648 */
++#line 4756 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 358:
+-#line 1065 "parser.y" /* yacc.c:1648 */
++#line 1063 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
+-#line 4767 "parser.tab.c" /* yacc.c:1648 */
++#line 4762 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 359:
+-#line 1066 "parser.y" /* yacc.c:1648 */
++#line 1064 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); }
+-#line 4773 "parser.tab.c" /* yacc.c:1648 */
++#line 4768 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 360:
+-#line 1067 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4779 "parser.tab.c" /* yacc.c:1648 */
++#line 1065 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4774 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 361:
+-#line 1068 "parser.y" /* yacc.c:1648 */
+- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
+-#line 4785 "parser.tab.c" /* yacc.c:1648 */
++#line 1066 "parser.y" /* yacc.c:1646 */
++ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
++#line 4780 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 362:
+-#line 1070 "parser.y" /* yacc.c:1648 */
++#line 1068 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = make_declarator(NULL);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4794 "parser.tab.c" /* yacc.c:1648 */
++#line 4789 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 363:
+-#line 1075 "parser.y" /* yacc.c:1648 */
++#line 1073 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-3].declarator);
+- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
+- (yyval.declarator)->type = NULL;
++ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
++ (yyval.declarator)->declspec.type = NULL;
+ }
+-#line 4803 "parser.tab.c" /* yacc.c:1648 */
++#line 4798 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 364:
+-#line 1082 "parser.y" /* yacc.c:1648 */
++#line 1080 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
+-#line 4809 "parser.tab.c" /* yacc.c:1648 */
++#line 4804 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 365:
+-#line 1083 "parser.y" /* yacc.c:1648 */
++#line 1081 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
+-#line 4815 "parser.tab.c" /* yacc.c:1648 */
++#line 4810 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 366:
+-#line 1086 "parser.y" /* yacc.c:1648 */
++#line 1084 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = NULL; }
+-#line 4821 "parser.tab.c" /* yacc.c:1648 */
++#line 4816 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 367:
+-#line 1087 "parser.y" /* yacc.c:1648 */
++#line 1085 "parser.y" /* yacc.c:1646 */
+ { (yyval.expr) = (yyvsp[0].expr); }
+-#line 4827 "parser.tab.c" /* yacc.c:1648 */
++#line 4822 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 368:
+-#line 1090 "parser.y" /* yacc.c:1648 */
++#line 1088 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->bits = (yyvsp[0].expr);
+ if (!(yyval.declarator)->bits && !(yyval.declarator)->var->name)
+ error_loc("unnamed fields are not allowed\n");
+ }
+-#line 4836 "parser.tab.c" /* yacc.c:1648 */
++#line 4831 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 369:
+-#line 1097 "parser.y" /* yacc.c:1648 */
++#line 1095 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
+-#line 4842 "parser.tab.c" /* yacc.c:1648 */
++#line 4837 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 370:
+-#line 1099 "parser.y" /* yacc.c:1648 */
++#line 1097 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
+-#line 4848 "parser.tab.c" /* yacc.c:1648 */
++#line 4843 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 371:
+-#line 1103 "parser.y" /* yacc.c:1648 */
++#line 1101 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[0].declarator); }
+-#line 4854 "parser.tab.c" /* yacc.c:1648 */
++#line 4849 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 372:
+-#line 1104 "parser.y" /* yacc.c:1648 */
++#line 1102 "parser.y" /* yacc.c:1646 */
+ { (yyval.declarator) = (yyvsp[-2].declarator); (yyvsp[-2].declarator)->var->eval = (yyvsp[0].expr); }
+-#line 4860 "parser.tab.c" /* yacc.c:1648 */
++#line 4855 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 373:
+-#line 1108 "parser.y" /* yacc.c:1648 */
++#line 1106 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_APARTMENT; }
+-#line 4866 "parser.tab.c" /* yacc.c:1648 */
++#line 4861 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 374:
+-#line 1109 "parser.y" /* yacc.c:1648 */
++#line 1107 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_NEUTRAL; }
+-#line 4872 "parser.tab.c" /* yacc.c:1648 */
++#line 4867 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 375:
+-#line 1110 "parser.y" /* yacc.c:1648 */
++#line 1108 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_SINGLE; }
+-#line 4878 "parser.tab.c" /* yacc.c:1648 */
++#line 4873 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 376:
+-#line 1111 "parser.y" /* yacc.c:1648 */
++#line 1109 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_FREE; }
+-#line 4884 "parser.tab.c" /* yacc.c:1648 */
++#line 4879 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 377:
+-#line 1112 "parser.y" /* yacc.c:1648 */
++#line 1110 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = THREADING_BOTH; }
+-#line 4890 "parser.tab.c" /* yacc.c:1648 */
++#line 4885 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 378:
+-#line 1116 "parser.y" /* yacc.c:1648 */
++#line 1114 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_RP; }
+-#line 4896 "parser.tab.c" /* yacc.c:1648 */
++#line 4891 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 379:
+-#line 1117 "parser.y" /* yacc.c:1648 */
++#line 1115 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_UP; }
+-#line 4902 "parser.tab.c" /* yacc.c:1648 */
++#line 4897 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 380:
+-#line 1118 "parser.y" /* yacc.c:1648 */
++#line 1116 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = FC_FP; }
+-#line 4908 "parser.tab.c" /* yacc.c:1648 */
++#line 4903 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 381:
+-#line 1121 "parser.y" /* yacc.c:1648 */
++#line 1119 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
+-#line 4914 "parser.tab.c" /* yacc.c:1648 */
++#line 4909 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 382:
+-#line 1124 "parser.y" /* yacc.c:1648 */
++#line 1122 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_void(); }
+-#line 4920 "parser.tab.c" /* yacc.c:1648 */
++#line 4915 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 383:
+-#line 1125 "parser.y" /* yacc.c:1648 */
++#line 1123 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
+-#line 4926 "parser.tab.c" /* yacc.c:1648 */
++#line 4921 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 384:
+-#line 1126 "parser.y" /* yacc.c:1648 */
++#line 1124 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4932 "parser.tab.c" /* yacc.c:1648 */
++#line 4927 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 385:
+-#line 1127 "parser.y" /* yacc.c:1648 */
++#line 1125 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4938 "parser.tab.c" /* yacc.c:1648 */
++#line 4933 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 386:
+-#line 1128 "parser.y" /* yacc.c:1648 */
++#line 1126 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 4944 "parser.tab.c" /* yacc.c:1648 */
++#line 4939 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 387:
+-#line 1129 "parser.y" /* yacc.c:1648 */
++#line 1127 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4950 "parser.tab.c" /* yacc.c:1648 */
++#line 4945 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 388:
+-#line 1130 "parser.y" /* yacc.c:1648 */
++#line 1128 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
+-#line 4956 "parser.tab.c" /* yacc.c:1648 */
++#line 4951 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 389:
+-#line 1131 "parser.y" /* yacc.c:1648 */
++#line 1129 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = (yyvsp[0].type); }
+-#line 4962 "parser.tab.c" /* yacc.c:1648 */
++#line 4957 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 390:
+-#line 1132 "parser.y" /* yacc.c:1648 */
++#line 1130 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
+-#line 4968 "parser.tab.c" /* yacc.c:1648 */
++#line 4963 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 391:
+-#line 1133 "parser.y" /* yacc.c:1648 */
++#line 1131 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = make_safearray((yyvsp[-1].type)); }
+-#line 4974 "parser.tab.c" /* yacc.c:1648 */
++#line 4969 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 392:
+-#line 1137 "parser.y" /* yacc.c:1648 */
++#line 1135 "parser.y" /* yacc.c:1646 */
+ { (yyvsp[-4].attr_list) = append_attribs((yyvsp[-4].attr_list), (yyvsp[-2].attr_list));
+ reg_typedefs((yyvsp[-1].declspec), (yyvsp[0].declarator_list), check_typedef_attrs((yyvsp[-4].attr_list)));
+ (yyval.statement) = make_statement_typedef((yyvsp[0].declarator_list));
+ }
+-#line 4983 "parser.tab.c" /* yacc.c:1648 */
++#line 4978 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 393:
+-#line 1144 "parser.y" /* yacc.c:1648 */
++#line 1142 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_nonencapsulated_union((yyvsp[-3].str), TRUE, (yyvsp[-1].var_list)); }
+-#line 4989 "parser.tab.c" /* yacc.c:1648 */
++#line 4984 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 394:
+-#line 1147 "parser.y" /* yacc.c:1648 */
++#line 1145 "parser.y" /* yacc.c:1646 */
+ { (yyval.type) = type_new_encapsulated_union((yyvsp[-8].str), (yyvsp[-5].var), (yyvsp[-3].var), (yyvsp[-1].var_list)); }
+-#line 4995 "parser.tab.c" /* yacc.c:1648 */
++#line 4990 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 395:
+-#line 1151 "parser.y" /* yacc.c:1648 */
++#line 1149 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); }
+-#line 5001 "parser.tab.c" /* yacc.c:1648 */
++#line 4996 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 396:
+-#line 1152 "parser.y" /* yacc.c:1648 */
++#line 1150 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); }
+-#line 5007 "parser.tab.c" /* yacc.c:1648 */
++#line 5002 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 397:
+-#line 1153 "parser.y" /* yacc.c:1648 */
++#line 1151 "parser.y" /* yacc.c:1646 */
+ { (yyval.num) = (yyvsp[0].num); }
+-#line 5013 "parser.tab.c" /* yacc.c:1648 */
++#line 5008 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 402:
+-#line 1166 "parser.y" /* yacc.c:1648 */
++#line 1164 "parser.y" /* yacc.c:1646 */
+ { type_t *type = find_type_or_error((yyvsp[-1].str), 0);
+ type->attrs = append_attr_list(type->attrs, (yyvsp[-2].attr_list));
+ }
+-#line 5021 "parser.tab.c" /* yacc.c:1648 */
++#line 5016 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 403:
+-#line 1171 "parser.y" /* yacc.c:1648 */
++#line 1169 "parser.y" /* yacc.c:1646 */
+ { type_t *iface = find_type_or_error2((yyvsp[-3].str), 0);
+ if (type_get_type(iface) != TYPE_INTERFACE)
+ error_loc("%s is not an interface\n", iface->name);
+ iface->attrs = append_attr_list(iface->attrs, (yyvsp[-5].attr_list));
+ }
+-#line 5031 "parser.tab.c" /* yacc.c:1648 */
++#line 5026 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 404:
+-#line 1178 "parser.y" /* yacc.c:1648 */
++#line 1176 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = NULL; }
+-#line 5037 "parser.tab.c" /* yacc.c:1648 */
++#line 5032 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 405:
+-#line 1179 "parser.y" /* yacc.c:1648 */
++#line 1177 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = (yyvsp[-1].attr_list); }
+-#line 5043 "parser.tab.c" /* yacc.c:1648 */
++#line 5038 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 406:
+-#line 1182 "parser.y" /* yacc.c:1648 */
++#line 1180 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr(NULL, (yyvsp[0].attr)); }
+-#line 5049 "parser.tab.c" /* yacc.c:1648 */
++#line 5044 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 407:
+-#line 1183 "parser.y" /* yacc.c:1648 */
++#line 1181 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr_list) = append_attr((yyvsp[-2].attr_list), (yyvsp[0].attr)); }
+-#line 5055 "parser.tab.c" /* yacc.c:1648 */
++#line 5050 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 408:
+-#line 1186 "parser.y" /* yacc.c:1648 */
++#line 1184 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_ENCODE); }
+-#line 5061 "parser.tab.c" /* yacc.c:1648 */
++#line 5056 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 409:
+-#line 1187 "parser.y" /* yacc.c:1648 */
++#line 1185 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_DECODE); }
+-#line 5067 "parser.tab.c" /* yacc.c:1648 */
++#line 5062 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+ case 410:
+-#line 1188 "parser.y" /* yacc.c:1648 */
++#line 1186 "parser.y" /* yacc.c:1646 */
+ { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
+-#line 5073 "parser.tab.c" /* yacc.c:1648 */
++#line 5068 "parser.tab.c" /* yacc.c:1646 */
+ break;
+
+
+-#line 5077 "parser.tab.c" /* yacc.c:1648 */
++#line 5072 "parser.tab.c" /* yacc.c:1646 */
+ default: break;
+ }
+ /* User semantic actions sometimes alter yychar, and that requires
+@@ -5301,7 +5296,7 @@ yyreturn:
+ #endif
+ return yyresult;
+ }
+-#line 1190 "parser.y" /* yacc.c:1907 */
++#line 1188 "parser.y" /* yacc.c:1906 */
+
+
+ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+@@ -5312,7 +5307,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+
+ static void decl_builtin_alias(const char *name, type_t *t)
+ {
+- reg_type(type_new_alias(t, name), name, NULL, 0);
++ decl_spec_t ds;
++ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
+ }
+
+ void init_types(void)
+@@ -5323,7 +5319,7 @@ void init_types(void)
+ decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
+ decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
+ decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
+- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
++ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
+ }
+
+ static str_list_t *append_str(str_list_t *list, char *str)
+@@ -5354,6 +5350,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
+ LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
+ if (attr_existing->type == attr->type)
+ {
++ __builtin_trap();
+ parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
+ /* use the last attribute, like MIDL does */
+ list_remove(&attr_existing->entry);
+@@ -5413,53 +5410,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
+ return new_list;
+ }
+
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
+ {
+ decl_spec_t *declspec = left ? left : right;
+ if (!declspec)
+ {
+ declspec = xmalloc(sizeof(*declspec));
+ declspec->type = NULL;
+- declspec->attrs = NULL;
+ declspec->stgclass = STG_NONE;
++ declspec->typequalifier = TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
+ }
+ declspec->type = type;
+ if (left && declspec != left)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = left->stgclass;
+ else if (left->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = left->typequalifier;
++ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = left->funcspecifier;
++ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!left->type);
+ free(left);
+ }
+ if (right && declspec != right)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = right->stgclass;
+ else if (right->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = right->typequalifier;
++ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = right->funcspecifier;
++ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!right->type);
+ free(right);
+ }
+
+- declspec->attrs = append_attr(declspec->attrs, attr);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = stgclass;
+ else if (stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
+
+- /* apply attributes to type */
+- if (type && declspec->attrs)
+- {
+- attr_list_t *attrs;
+- declspec->type = duptype(type, 1);
+- attrs = map_attrs(type->attrs, NULL);
+- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+- declspec->attrs = NULL;
+- }
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = typequalifier;
++ else if (typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = funcspecifier;
++ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
+
+ return declspec;
+ }
+@@ -5545,6 +5562,7 @@ void clear_all_offsets(void)
+
+ static void type_function_add_head_arg(type_t *type, var_t *arg)
+ {
++ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
+ if (!type->details.function->args)
+ {
+ type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
+@@ -5589,31 +5607,60 @@ static int is_allowed_range_type(const type_t *type)
+ static type_t *get_array_or_ptr_ref(type_t *type)
+ {
+ if (is_ptr(type))
+- return type_pointer_get_ref(type);
++ return type_pointer_get_ref_type(type);
+ else if (is_array(type))
+- return type_array_get_element(type);
++ return type_array_get_element_type(type);
+ return NULL;
+ }
+
+ static type_t *append_chain_type(type_t *chain, type_t *type)
+ {
+- type_t *chain_type;
++ type_t *chain_type = NULL;
+
+ if (!chain)
+ return type;
+ for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
+ ;
+
++ assert(!type_is_alias(chain_type));
+ if (is_ptr(chain_type))
+- chain_type->details.pointer.ref = type;
++ chain_type->details.pointer.ref.type = type;
+ else if (is_array(chain_type))
+- chain_type->details.array.elem = type;
++ chain_type->details.array.elem.type = type;
+ else
+ assert(0);
+
+ return chain;
+ }
+
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
++{
++ type_t *chain_type = chain->type;
++ decl_spec_t *chain_declspec = NULL;
++
++ if (!chain_type)
++ {
++ chain->type = type;
++ chain->typequalifier = typequalifier;
++ return chain;
++ }
++
++ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
++ ;
++
++ if (is_ptr(chain_type))
++ chain_declspec = &chain_type->details.pointer.ref;
++ else if (is_array(chain_type))
++ chain_declspec = &chain_type->details.array.elem;
++ else
++ assert(NULL);
++
++ chain_declspec->type = type;
++ chain_declspec->typequalifier = typequalifier;
++
++ return chain;
++}
++
+ static warning_list_t *append_warning(warning_list_t *list, int num)
+ {
+ warning_t *entry;
+@@ -5629,7 +5676,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
+ return list;
+ }
+
+-static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
++static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
+ int top)
+ {
+ var_t *v = decl->var;
+@@ -5638,58 +5685,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ expr_t *dim;
+ type_t **ptype;
+ type_t *func_type = decl ? decl->func_type : NULL;
+- type_t *type = decl_spec->type;
++ type_t *type = declspec->type;
+
+- if (is_attr(type->attrs, ATTR_INLINE))
+- {
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
+ if (!func_type)
+ error_loc("inline attribute applied to non-function type\n");
+ else
+ {
+- type_t *t;
+- /* move inline attribute from return type node to function node */
+- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
+- ;
+- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
++ v->declspec.funcspecifier = declspec->funcspecifier;
+ }
+ }
+
+- /* 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;
++ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
++ * unless the pointee already has const type qualifier*/
++ if (!decl)
++ {
++ /* simplest case, no pointers to deal with here */
++ v->declspec.typequalifier = declspec->typequalifier;
++ } else if (decl->bits)
++ {
++ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
++ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
++ v->declspec.typequalifier = declspec->typequalifier;
++ }
++ else
++ {
++ /* here we're dealing with a pointerish type chain, so we need to pull
++ * the typequalifier off of the declspec and stick them in the type's attr list
++ */
++ v->declspec.type = decl->declspec.type;
++ v->declspec.typequalifier = decl->declspec.typequalifier;
++ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
++ }
++
++ v->declspec.stgclass = declspec->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);
+ if (!ptr_attr && type_is_alias(ptr))
+- ptr = type_alias_get_aliasee(ptr);
++ ptr = type_alias_get_aliasee_type(ptr);
+ else
+ break;
+ }
+ if (is_ptr(ptr))
+ {
+ if (ptr_attr && ptr_attr != FC_UP &&
+- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
++ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
+ warning_loc_info(&v->loc_info,
+ "%s: pointer attribute applied to interface "
+ "pointer type has no effect\n", v->name);
+- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
++ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
+ {
++ printf("dup_pointer_type!\n");
++ printf("type : %p name : %s\n", *pt, (*pt)->name);
++ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
++ /* *pt could be the var's declspec's type OR a type on a typedef */
++ /* not an array */
++
+ /* FIXME: this is a horrible hack to cope with the issue that we
+ * store an offset to the typeformat string in the type object, but
+ * two typeformat strings may be written depending on whether the
+ * pointer is a toplevel parameter or not */
+- *pt = duptype(*pt, 1);
++ *pt = dup_pointer_type(*pt);
+ }
+ }
+ else if (ptr_attr)
+@@ -5700,16 +5769,16 @@ 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);
+
+ for (;;)
+ {
+ if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ else if (is_array(t))
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ else
+ break;
+ }
+@@ -5726,15 +5795,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)
+@@ -5747,7 +5816,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ else
+ *ptype = type_new_array((*ptype)->name,
+ type_array_get_element(*ptype), FALSE,
+- 0, dim, NULL, 0);
++ 0, dim, NULL, FC_RP);
+ }
+ else if (is_ptr(*ptype))
+ *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
+@@ -5756,15 +5825,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: size_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ 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)
+@@ -5782,10 +5852,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: length_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in length_is attribute\n", v->name);
+ }
+@@ -5796,29 +5867,31 @@ 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;
++ enum type_qualifier typequalifier = v->declspec.typequalifier;
++
++ v->declspec.type = func_type;
++ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
++ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(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;
++ ft->details.function->retval->declspec.typequalifier = typequalifier;
++
+ /* 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_type(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_type(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);
+-
+ return v;
+ }
+
+@@ -5866,6 +5939,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+ list_init( list );
+ }
+ list_add_tail( list, &var->entry );
++
++ if (var->declspec.type)
++ var->declonly = !type_is_defined(var->declspec.type);
++
+ return list;
+ }
+
+@@ -5885,11 +5962,11 @@ 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);
++ v->declonly = TRUE;
+ return v;
+ }
+
+@@ -5897,10 +5974,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;
+ }
+@@ -5920,7 +5996,7 @@ static declarator_t *make_declarator(var_t *var)
+ {
+ declarator_t *d = xmalloc(sizeof(*d));
+ d->var = var ? var : make_var(NULL);
+- d->type = NULL;
++ init_declspec(&d->declspec, NULL);
+ d->func_type = NULL;
+ d->bits = NULL;
+ return d;
+@@ -5928,7 +6004,15 @@ static declarator_t *make_declarator(var_t *var)
+
+ static type_t *make_safearray(type_t *type)
+ {
+- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
++ decl_spec_t aliasee_ds;
++ decl_spec_t element_ds;
++
++ init_declspec(&element_ds,
++ type_new_alias(
++ init_declspec(&aliasee_ds, type),
++ "SAFEARRAY"));
++
++ return type_new_array(NULL, &element_ds, TRUE, 0,
+ NULL, NULL, FC_RP);
+ }
+
+@@ -6007,6 +6091,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ }
+ if (!namespace)
+ namespace = &global_namespace;
++ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
++
+ hash = hash_ident(name);
+ nt = xmalloc(sizeof(struct rtype));
+ nt->name = name;
+@@ -6018,15 +6104,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ nt->t = t;
+ nt->next = namespace->type_hash[hash];
+ namespace->type_hash[hash] = nt;
+- if ((t == tsSTRUCT || t == tsUNION))
++ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
+ fix_incomplete_types(type);
+ return type;
+ }
+
+ static int is_incomplete(const type_t *t)
+ {
+- return !t->defined &&
+- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
++ return !type_is_defined(t) &&
++ (type_get_type_detect_alias(t) == TYPE_ENUM ||
++ type_get_type_detect_alias(t) == TYPE_STRUCT ||
+ type_get_type_detect_alias(t) == TYPE_UNION ||
+ type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
+ }
+@@ -6034,19 +6121,16 @@ static int is_incomplete(const type_t *t)
+ void add_incomplete(type_t *t)
+ {
+ struct typenode *tn = xmalloc(sizeof *tn);
++ assert(is_incomplete(t));
+ tn->type = t;
+ list_add_tail(&incomplete_types, &tn->entry);
+ }
+
+ static void fix_type(type_t *t)
+ {
+- if (type_is_alias(t) && is_incomplete(t)) {
+- type_t *ot = type_alias_get_aliasee(t);
+- fix_type(ot);
+- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
+- type_get_type_detect_alias(ot) == TYPE_UNION ||
+- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
+- t->details.structure = ot->details.structure;
++ if (type_is_alias(t) && is_incomplete(t))
++ {
++ type_t *ot = type_alias_get_aliasee_type(t);
+ t->defined = ot->defined;
+ }
+ }
+@@ -6070,7 +6154,7 @@ static void fix_incomplete_types(type_t *complete_type)
+ {
+ if (type_is_equal(complete_type, tn->type))
+ {
+- tn->type->details.structure = complete_type->details.structure;
++ tn->type->details = complete_type->details;
+ list_remove(&tn->entry);
+ free(tn);
+ }
+@@ -6094,7 +6178,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ if (!type->name)
++ {
+ type->name = gen_name();
++ /* the generated name will be used and this typedef excluded from the
++ * built typelib unless the typedef has the 'public' attribute, so add it here */
++ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
++ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
++ }
+
+ /* replace existing attributes when generating a typelib */
+ if (do_typelib)
+@@ -6120,12 +6210,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ * for cleaner solution.
+ */
+ if (cur && input_name == cur->loc_info.input_name)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
+ cur->name, cur->loc_info.input_name,
+ 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, name->name);
+ cur->attrs = attrs;
+
+ if (is_incomplete(cur))
+@@ -6140,6 +6230,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
+ {
+ struct rtype *cur;
+
++ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
++
+ if(namespace && namespace != &global_namespace) {
+ for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
+ if(cur->t == t && !strcmp(cur->name, name))
+@@ -6293,7 +6385,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
+ /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+@@ -6328,7 +6419,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
+@@ -6400,10 +6490,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);
+@@ -6608,7 +6698,7 @@ static int is_ptr_guid_type(const type_t *type)
+
+ /* second, make sure it is a pointer to something of size sizeof(GUID),
+ * i.e. 16 bytes */
+- return (type_memsize(type_pointer_get_ref(type)) == 16);
++ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
+ }
+
+ static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+@@ -6635,7 +6725,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;
+@@ -6665,7 +6755,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);
+@@ -6762,23 +6852,28 @@ static void check_field_common(const type_t *container_type,
+ {
+ const type_t *t = type;
+ while (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ if (is_aliaschain_attr(t, ATTR_RANGE))
+ warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ more_to_do = TRUE;
+ break;
+ case TGT_ARRAY:
+- type = type_array_get_element(type);
++ type = type_array_get_element_type(type);
+ more_to_do = TRUE;
+ break;
++ case TGT_ENUM:
++ type = type_get_real_type(type);
++ if(!type_is_complete(type))
++ {
++ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
++ }
+ case TGT_USER_TYPE:
+ case TGT_IFACE_POINTER:
+ case TGT_BASIC:
+- case TGT_ENUM:
+ case TGT_RANGE:
+ /* nothing to do */
+ break;
+@@ -6803,13 +6898,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+ if (type_is_complete(type))
+ fields = type_struct_get_fields(type);
+ else
+- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
++ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
+ }
+ else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+- fields = type_union_get_cases(type);
++ {
++ if (type_is_complete(type))
++ fields = type_union_get_cases(type);
++ else
++ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
++ }
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+- if (field->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 */
+@@ -6818,9 +6918,10 @@ 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 )
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
+ {
+- const type_t *type = arg->type;
++ const type_t *type = arg->declspec.type;
+
+ /* check that [out] parameters have enough pointer levels */
+ if (is_attr(arg->attrs, ATTR_OUT))
+@@ -6860,16 +6961,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);
+ }
+ }
+@@ -6886,8 +6987,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);
+ }
+ }
+
+@@ -6952,6 +7053,7 @@ static void check_async_uuid(type_t *iface)
+ type_t *async_iface;
+ type_t *inherit;
+
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
+
+ inherit = iface->details.iface->inherit;
+@@ -6968,7 +7070,8 @@ 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;
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ args = func->declspec.type->details.function->args;
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+ if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
+@@ -6978,15 +7081,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));
+ }
+
+@@ -7026,6 +7129,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+ static void check_all_user_types(const statement_list_t *stmts)
+ {
+ const statement_t *stmt;
++ const var_t *v;
+
+ if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
+ {
+@@ -7037,7 +7141,11 @@ 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;
+- check_for_additional_prototype_types(func->type->details.function->args);
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args)
++ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
++ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
+ }
+ }
+ }
+@@ -7071,6 +7179,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+ {
+ statement_t *stmt = make_statement(STMT_TYPE);
+ stmt->u.type = type;
++ if (type_is_defined(type))
++ {
++ stmt->declonly = FALSE;
++ }
+ return stmt;
+ }
+
+@@ -7085,16 +7197,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;
+ }
+@@ -7146,6 +7258,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ declarator_t *decl, *next;
+ statement_t *stmt;
+ type_list_t **type_list;
++ int defined = TRUE;
+
+ if (!decls) return NULL;
+
+@@ -7157,6 +7270,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ {
+ var_t *var = decl->var;
+ type_t *type = find_type_or_error(var->name, 0);
++
++ /* ensure that all of the types in this typedef statement have been defined
++ * before setting its declonly flag */
++ if (type_is_pointerish(type))
++ {
++ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
++ }
++ else
++ {
++ defined = defined & type_is_defined(type_get_real_type(type));
++ }
++
+ *type_list = xmalloc(sizeof(type_list_t));
+ (*type_list)->type = type;
+ (*type_list)->next = NULL;
+@@ -7166,6 +7291,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ free(var);
+ }
+
++ stmt->declonly = !defined;
+ return stmt;
+ }
+
+@@ -7206,7 +7332,7 @@ void init_loc_info(loc_info_t *i)
+
+ static void check_def(const type_t *t)
+ {
+- if (t->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type_is_defined(t))
++ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ t->name, t->loc_info.input_name, t->loc_info.line_number);
+ }
+diff --git a/mingw-w64-tools/widl/src/parser.tab.h b/mingw-w64-tools/widl/src/parser.tab.h
+index 09874726..fc7a8f4d 100644
+--- a/mingw-w64-tools/widl/src/parser.tab.h
++++ b/mingw-w64-tools/widl/src/parser.tab.h
+@@ -1,8 +1,8 @@
+-/* A Bison parser, made by GNU Bison 3.0.5. */
++/* A Bison parser, made by GNU Bison 3.0.4. */
+
+ /* Bison interface for Yacc-like parsers in C
+
+- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
++ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+@@ -239,7 +239,7 @@ extern int parser_debug;
+
+ union YYSTYPE
+ {
+-#line 142 "parser.y" /* yacc.c:1910 */
++#line 136 "parser.y" /* yacc.c:1909 */
+
+ attr_t *attr;
+ attr_list_t *attr_list;
+@@ -266,8 +266,10 @@ union YYSTYPE
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+
+-#line 271 "parser.tab.h" /* yacc.c:1910 */
++#line 273 "parser.tab.h" /* yacc.c:1909 */
+ };
+
+ typedef union YYSTYPE YYSTYPE;
+diff --git a/mingw-w64-tools/widl/src/parser.y b/mingw-w64-tools/widl/src/parser.y
+index d9793941..bb14bf76 100644
+--- a/mingw-w64-tools/widl/src/parser.y
++++ b/mingw-w64-tools/widl/src/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);
+@@ -67,7 +60,7 @@ static void fix_incomplete_types(type_t *complete_type);
+ static str_list_t *append_str(str_list_t *list, char *str);
+ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
+ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
+ static attr_t *make_attr(enum attr_type type);
+ static attr_t *make_attrv(enum attr_type type, unsigned int val);
+ static attr_t *make_attrp(enum attr_type type, void *val);
+@@ -83,6 +76,7 @@ static declarator_t *make_declarator(var_t *var);
+ static type_t *make_safearray(type_t *type);
+ static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+ static type_t *append_chain_type(type_t *chain, type_t *type);
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
+ static warning_list_t *append_warning(warning_list_t *, int);
+
+ static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+@@ -165,6 +159,8 @@ static typelib_t *current_typelib;
+ struct _import_t *import;
+ struct _decl_spec_t *declspec;
+ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
+ }
+
+ %token <str> aIDENTIFIER aPRAGMA
+@@ -266,14 +262,16 @@ static typelib_t *current_typelib;
+ %token tWCHAR tWIREMARSHAL
+ %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
+
+-%type <attr> attribute type_qualifier function_specifier acf_attribute
+-%type <attr_list> m_attributes attributes attrib_list m_type_qual_list
++%type <attr> attribute acf_attribute
++%type <attr_list> m_attributes attributes attrib_list
+ %type <attr_list> acf_attributes acf_attribute_list
+ %type <str_list> str_list
+ %type <expr> m_expr expr expr_const expr_int_const array m_bitfield
+ %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
+ %type <ifinfo> interfacehdr
+ %type <stgclass> storage_cls_spec
++%type <typequalifier> type_qualifier m_type_qual_bits
++%type <funcspecifier> function_specifier
+ %type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
+ %type <type> inherit interface interfacedef interfacedec
+ %type <type> dispinterface dispinterfacehdr dispinterfacedef
+@@ -318,7 +316,7 @@ static typelib_t *current_typelib;
+ %right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
+ %left '.' MEMBERPTR '[' ']'
+
+-%error-verbose
++%define parse.error verbose
+
+ %%
+
+@@ -651,10 +649,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 +738,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 +762,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);
+ }
+@@ -955,20 +953,20 @@ storage_cls_spec:
+ ;
+
+ function_specifier:
+- tINLINE { $$ = make_attr(ATTR_INLINE); }
++ tINLINE { $$ = FUNCTION_SPECIFIER_INLINE; }
+ ;
+
+ type_qualifier:
+- tCONST { $$ = make_attr(ATTR_CONST); }
++ tCONST { $$ = TYPE_QUALIFIER_CONST; }
+ ;
+
+-m_type_qual_list: { $$ = NULL; }
+- | m_type_qual_list type_qualifier { $$ = append_attr($1, $2); }
++m_type_qual_bits: { $$ = TYPE_QUALIFIER_NONE; }
++ | m_type_qual_bits type_qualifier { $$ = $1 | $2; }
+ ;
+
+-decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); }
++decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ | decl_spec_no_type type m_decl_spec_no_type
+- { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); }
++ { $$ = make_decl_spec($2, $1, $3, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ ;
+
+ m_decl_spec_no_type: { $$ = NULL; }
+@@ -976,44 +974,44 @@ m_decl_spec_no_type: { $$ = NULL; }
+ ;
+
+ decl_spec_no_type:
+- type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
+- | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
+- | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); }
++ type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, $1, FUNCTION_SPECIFIER_NONE); }
++ | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, $1); }
++ | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
+ ;
+
+ declarator:
+- '*' m_type_qual_list declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | direct_declarator
+ ;
+
+ direct_declarator:
+ ident { $$ = make_declarator($1); }
+ | '(' declarator ')' { $$ = $2; }
+- | direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
++ | direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
+ | direct_declarator '(' m_args ')' { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+ /* abstract declarator */
+ abstract_declarator:
+- '*' m_type_qual_list m_abstract_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits m_abstract_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv m_abstract_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | abstract_direct_declarator
+ ;
+
+ /* abstract declarator without accepting direct declarator */
+ abstract_declarator_no_direct:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
+ | callconv m_any_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
+- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ ;
+
+ /* abstract declarator or empty */
+@@ -1024,33 +1022,33 @@ m_abstract_declarator: { $$ = make_declarator(NULL); }
+ /* abstract direct declarator */
+ abstract_direct_declarator:
+ '(' abstract_declarator_no_direct ')' { $$ = $2; }
+- | abstract_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
+- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
++ | abstract_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
++ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
+ | '(' m_args ')'
+ { $$ = make_declarator(NULL);
+- $$->func_type = append_chain_type($$->type, type_new_function($2));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
++ $$->declspec.type = NULL;
+ }
+ | abstract_direct_declarator '(' m_args ')'
+ { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+ /* abstract or non-abstract declarator */
+ any_declarator:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
+- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
++ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ | any_direct_declarator
+ ;
+
+ /* abstract or non-abstract declarator without accepting direct declarator */
+ any_declarator_no_direct:
+- '*' m_type_qual_list m_any_declarator %prec PPTR
+- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
+- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
++ '*' m_type_qual_bits m_any_declarator %prec PPTR
++ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
++ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+ ;
+
+ /* abstract or non-abstract declarator or empty */
+@@ -1064,17 +1062,17 @@ m_any_declarator: { $$ = make_declarator(NULL); }
+ any_direct_declarator:
+ ident { $$ = make_declarator($1); }
+ | '(' any_declarator_no_direct ')' { $$ = $2; }
+- | any_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
+- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
++ | any_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
++ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
+ | '(' m_args ')'
+ { $$ = make_declarator(NULL);
+- $$->func_type = append_chain_type($$->type, type_new_function($2));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
++ $$->declspec.type = NULL;
+ }
+ | any_direct_declarator '(' m_args ')'
+ { $$ = $1;
+- $$->func_type = append_chain_type($$->type, type_new_function($3));
+- $$->type = NULL;
++ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
++ $$->declspec.type = NULL;
+ }
+ ;
+
+@@ -1197,7 +1195,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
+
+ static void decl_builtin_alias(const char *name, type_t *t)
+ {
+- reg_type(type_new_alias(t, name), name, NULL, 0);
++ decl_spec_t ds;
++ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
+ }
+
+ void init_types(void)
+@@ -1208,7 +1207,7 @@ void init_types(void)
+ decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
+ decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
+ decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
+- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
++ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
+ }
+
+ static str_list_t *append_str(str_list_t *list, char *str)
+@@ -1239,6 +1238,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
+ LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
+ if (attr_existing->type == attr->type)
+ {
++ __builtin_trap();
+ parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
+ /* use the last attribute, like MIDL does */
+ list_remove(&attr_existing->entry);
+@@ -1298,53 +1298,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
+ return new_list;
+ }
+
+-static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
++static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
+ {
+ decl_spec_t *declspec = left ? left : right;
+ if (!declspec)
+ {
+ declspec = xmalloc(sizeof(*declspec));
+ declspec->type = NULL;
+- declspec->attrs = NULL;
+ declspec->stgclass = STG_NONE;
++ declspec->typequalifier = TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
+ }
+ declspec->type = type;
+ if (left && declspec != left)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = left->stgclass;
+ else if (left->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = left->typequalifier;
++ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = left->funcspecifier;
++ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!left->type);
+ free(left);
+ }
+ if (right && declspec != right)
+ {
+- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = right->stgclass;
+ else if (right->stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
++
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = right->typequalifier;
++ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = right->funcspecifier;
++ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
++
+ assert(!right->type);
+ free(right);
+ }
+
+- declspec->attrs = append_attr(declspec->attrs, attr);
+ if (declspec->stgclass == STG_NONE)
+ declspec->stgclass = stgclass;
+ else if (stgclass != STG_NONE)
+ error_loc("only one storage class can be specified\n");
+
+- /* apply attributes to type */
+- if (type && declspec->attrs)
+- {
+- attr_list_t *attrs;
+- declspec->type = duptype(type, 1);
+- attrs = map_attrs(type->attrs, NULL);
+- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+- declspec->attrs = NULL;
+- }
++ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
++ declspec->typequalifier = typequalifier;
++ else if (typequalifier != TYPE_QUALIFIER_NONE)
++ error_loc("only one type qualifier can be specified\n");
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
++ declspec->funcspecifier = funcspecifier;
++ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
++ error_loc("only one function specifier can be specified\n");
+
+ return declspec;
+ }
+@@ -1430,6 +1450,7 @@ void clear_all_offsets(void)
+
+ static void type_function_add_head_arg(type_t *type, var_t *arg)
+ {
++ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
+ if (!type->details.function->args)
+ {
+ type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
+@@ -1474,31 +1495,60 @@ static int is_allowed_range_type(const type_t *type)
+ static type_t *get_array_or_ptr_ref(type_t *type)
+ {
+ if (is_ptr(type))
+- return type_pointer_get_ref(type);
++ return type_pointer_get_ref_type(type);
+ else if (is_array(type))
+- return type_array_get_element(type);
++ return type_array_get_element_type(type);
+ return NULL;
+ }
+
+ static type_t *append_chain_type(type_t *chain, type_t *type)
+ {
+- type_t *chain_type;
++ type_t *chain_type = NULL;
+
+ if (!chain)
+ return type;
+ for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
+ ;
+
++ assert(!type_is_alias(chain_type));
+ if (is_ptr(chain_type))
+- chain_type->details.pointer.ref = type;
++ chain_type->details.pointer.ref.type = type;
+ else if (is_array(chain_type))
+- chain_type->details.array.elem = type;
++ chain_type->details.array.elem.type = type;
+ else
+ assert(0);
+
+ return chain;
+ }
+
++static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
++{
++ type_t *chain_type = chain->type;
++ decl_spec_t *chain_declspec = NULL;
++
++ if (!chain_type)
++ {
++ chain->type = type;
++ chain->typequalifier = typequalifier;
++ return chain;
++ }
++
++ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
++ ;
++
++ if (is_ptr(chain_type))
++ chain_declspec = &chain_type->details.pointer.ref;
++ else if (is_array(chain_type))
++ chain_declspec = &chain_type->details.array.elem;
++ else
++ assert(NULL);
++
++ chain_declspec->type = type;
++ chain_declspec->typequalifier = typequalifier;
++
++ return chain;
++}
++
+ static warning_list_t *append_warning(warning_list_t *list, int num)
+ {
+ warning_t *entry;
+@@ -1514,7 +1564,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
+ return list;
+ }
+
+-static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
++static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
+ int top)
+ {
+ var_t *v = decl->var;
+@@ -1523,58 +1573,80 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ expr_t *dim;
+ type_t **ptype;
+ type_t *func_type = decl ? decl->func_type : NULL;
+- type_t *type = decl_spec->type;
++ type_t *type = declspec->type;
+
+- if (is_attr(type->attrs, ATTR_INLINE))
+- {
++
++ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
+ if (!func_type)
+ error_loc("inline attribute applied to non-function type\n");
+ else
+ {
+- type_t *t;
+- /* move inline attribute from return type node to function node */
+- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
+- ;
+- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
++ v->declspec.funcspecifier = declspec->funcspecifier;
+ }
+ }
+
+- /* 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;
++ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
++ * unless the pointee already has const type qualifier*/
++ if (!decl)
++ {
++ /* simplest case, no pointers to deal with here */
++ v->declspec.typequalifier = declspec->typequalifier;
++ } else if (decl->bits)
++ {
++ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
++ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
++ v->declspec.typequalifier = declspec->typequalifier;
++ }
++ else
++ {
++ /* here we're dealing with a pointerish type chain, so we need to pull
++ * the typequalifier off of the declspec and stick them in the type's attr list
++ */
++ v->declspec.type = decl->declspec.type;
++ v->declspec.typequalifier = decl->declspec.typequalifier;
++ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
++ }
++
++ v->declspec.stgclass = declspec->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);
+ if (!ptr_attr && type_is_alias(ptr))
+- ptr = type_alias_get_aliasee(ptr);
++ ptr = type_alias_get_aliasee_type(ptr);
+ else
+ break;
+ }
+ if (is_ptr(ptr))
+ {
+ if (ptr_attr && ptr_attr != FC_UP &&
+- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
++ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
+ warning_loc_info(&v->loc_info,
+ "%s: pointer attribute applied to interface "
+ "pointer type has no effect\n", v->name);
+- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
++ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
+ {
++ printf("dup_pointer_type!\n");
++ printf("type : %p name : %s\n", *pt, (*pt)->name);
++ /* ptr_attr is ref,unique or full (FC_RP, FC_UP, FC_FP) */
++ /* *pt could be the var's declspec's type OR a type on a typedef */
++ /* not an array */
++
+ /* FIXME: this is a horrible hack to cope with the issue that we
+ * store an offset to the typeformat string in the type object, but
+ * two typeformat strings may be written depending on whether the
+ * pointer is a toplevel parameter or not */
+- *pt = duptype(*pt, 1);
++ *pt = dup_pointer_type(*pt);
+ }
+ }
+ else if (ptr_attr)
+@@ -1585,16 +1657,16 @@ 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);
+
+ for (;;)
+ {
+ if (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ else if (is_array(t))
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ else
+ break;
+ }
+@@ -1611,15 +1683,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)
+@@ -1632,7 +1704,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ else
+ *ptype = type_new_array((*ptype)->name,
+ type_array_get_element(*ptype), FALSE,
+- 0, dim, NULL, 0);
++ 0, dim, NULL, FC_RP);
+ }
+ else if (is_ptr(*ptype))
+ *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
+@@ -1641,15 +1713,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: size_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ 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)
+@@ -1667,10 +1740,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
+ error_loc("%s: length_is attribute applied to illegal type\n", v->name);
+ }
+
++ assert(!type_is_alias(*ptype));
+ if (is_ptr(*ptype))
+- ptype = &(*ptype)->details.pointer.ref;
++ ptype = &(*ptype)->details.pointer.ref.type;
+ else if (is_array(*ptype))
+- ptype = &(*ptype)->details.array.elem;
++ ptype = &(*ptype)->details.array.elem.type;
+ else
+ error_loc("%s: too many expressions in length_is attribute\n", v->name);
+ }
+@@ -1681,29 +1755,31 @@ 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;
++ enum type_qualifier typequalifier = v->declspec.typequalifier;
++
++ v->declspec.type = func_type;
++ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
++ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(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;
++ ft->details.function->retval->declspec.typequalifier = typequalifier;
++
+ /* 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_type(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_type(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);
+-
+ return v;
+ }
+
+@@ -1751,6 +1827,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
+ list_init( list );
+ }
+ list_add_tail( list, &var->entry );
++
++ if (var->declspec.type)
++ var->declonly = !type_is_defined(var->declspec.type);
++
+ return list;
+ }
+
+@@ -1770,11 +1850,11 @@ 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);
++ v->declonly = TRUE;
+ return v;
+ }
+
+@@ -1782,10 +1862,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;
+ }
+@@ -1805,7 +1884,7 @@ static declarator_t *make_declarator(var_t *var)
+ {
+ declarator_t *d = xmalloc(sizeof(*d));
+ d->var = var ? var : make_var(NULL);
+- d->type = NULL;
++ init_declspec(&d->declspec, NULL);
+ d->func_type = NULL;
+ d->bits = NULL;
+ return d;
+@@ -1813,7 +1892,15 @@ static declarator_t *make_declarator(var_t *var)
+
+ static type_t *make_safearray(type_t *type)
+ {
+- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
++ decl_spec_t aliasee_ds;
++ decl_spec_t element_ds;
++
++ init_declspec(&element_ds,
++ type_new_alias(
++ init_declspec(&aliasee_ds, type),
++ "SAFEARRAY"));
++
++ return type_new_array(NULL, &element_ds, TRUE, 0,
+ NULL, NULL, FC_RP);
+ }
+
+@@ -1892,6 +1979,8 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ }
+ if (!namespace)
+ namespace = &global_namespace;
++ printf("reg_type { name : %s, namespace : %s, type : %s, ptr : %p}\n", name, namespace->name, ts_to_str(t), type);
++
+ hash = hash_ident(name);
+ nt = xmalloc(sizeof(struct rtype));
+ nt->name = name;
+@@ -1903,15 +1992,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
+ nt->t = t;
+ nt->next = namespace->type_hash[hash];
+ namespace->type_hash[hash] = nt;
+- if ((t == tsSTRUCT || t == tsUNION))
++ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
+ fix_incomplete_types(type);
+ return type;
+ }
+
+ static int is_incomplete(const type_t *t)
+ {
+- return !t->defined &&
+- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
++ return !type_is_defined(t) &&
++ (type_get_type_detect_alias(t) == TYPE_ENUM ||
++ type_get_type_detect_alias(t) == TYPE_STRUCT ||
+ type_get_type_detect_alias(t) == TYPE_UNION ||
+ type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
+ }
+@@ -1919,19 +2009,16 @@ static int is_incomplete(const type_t *t)
+ void add_incomplete(type_t *t)
+ {
+ struct typenode *tn = xmalloc(sizeof *tn);
++ assert(is_incomplete(t));
+ tn->type = t;
+ list_add_tail(&incomplete_types, &tn->entry);
+ }
+
+ static void fix_type(type_t *t)
+ {
+- if (type_is_alias(t) && is_incomplete(t)) {
+- type_t *ot = type_alias_get_aliasee(t);
+- fix_type(ot);
+- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
+- type_get_type_detect_alias(ot) == TYPE_UNION ||
+- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
+- t->details.structure = ot->details.structure;
++ if (type_is_alias(t) && is_incomplete(t))
++ {
++ type_t *ot = type_alias_get_aliasee_type(t);
+ t->defined = ot->defined;
+ }
+ }
+@@ -1955,7 +2042,7 @@ static void fix_incomplete_types(type_t *complete_type)
+ {
+ if (type_is_equal(complete_type, tn->type))
+ {
+- tn->type->details.structure = complete_type->details.structure;
++ tn->type->details = complete_type->details;
+ list_remove(&tn->entry);
+ free(tn);
+ }
+@@ -1979,7 +2066,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
+ {
+ if (!type->name)
++ {
+ type->name = gen_name();
++ /* the generated name will be used and this typedef excluded from the
++ * built typelib unless the typedef has the 'public' attribute, so add it here */
++ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
++ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
++ }
+
+ /* replace existing attributes when generating a typelib */
+ if (do_typelib)
+@@ -2005,12 +2098,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
+ * for cleaner solution.
+ */
+ if (cur && input_name == cur->loc_info.input_name)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ error_loc("FOO %s: redefinition error; original definition was at %s:%d\n",
+ cur->name, cur->loc_info.input_name,
+ 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, name->name);
+ cur->attrs = attrs;
+
+ if (is_incomplete(cur))
+@@ -2025,6 +2118,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
+ {
+ struct rtype *cur;
+
++ printf("find_type { name : %s, namespace %s, type : %s }\n", name, namespace ? namespace->name : NULL, ts_to_str(t));
++
+ if(namespace && namespace != &global_namespace) {
+ for(cur = namespace->type_hash[hash_ident(name)]; cur; cur = cur->next) {
+ if(cur->t == t && !strcmp(cur->name, name))
+@@ -2178,7 +2273,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+ /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
+ /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
+- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
+ /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
+ /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
+ /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
+@@ -2213,7 +2307,6 @@ struct allowed_attr allowed_attr[] =
+ /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
+ /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
+ /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
+- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
+ /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
+ /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
+ /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
+@@ -2285,10 +2378,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);
+@@ -2493,7 +2586,7 @@ static int is_ptr_guid_type(const type_t *type)
+
+ /* second, make sure it is a pointer to something of size sizeof(GUID),
+ * i.e. 16 bytes */
+- return (type_memsize(type_pointer_get_ref(type)) == 16);
++ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
+ }
+
+ static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+@@ -2520,7 +2613,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 +2643,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);
+@@ -2647,23 +2740,28 @@ static void check_field_common(const type_t *container_type,
+ {
+ const type_t *t = type;
+ while (is_ptr(t))
+- t = type_pointer_get_ref(t);
++ t = type_pointer_get_ref_type(t);
+ if (is_aliaschain_attr(t, ATTR_RANGE))
+ warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ more_to_do = TRUE;
+ break;
+ case TGT_ARRAY:
+- type = type_array_get_element(type);
++ type = type_array_get_element_type(type);
+ more_to_do = TRUE;
+ break;
++ case TGT_ENUM:
++ type = type_get_real_type(type);
++ if(!type_is_complete(type))
++ {
++ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
++ }
+ case TGT_USER_TYPE:
+ case TGT_IFACE_POINTER:
+ case TGT_BASIC:
+- case TGT_ENUM:
+ case TGT_RANGE:
+ /* nothing to do */
+ break;
+@@ -2688,13 +2786,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
+ if (type_is_complete(type))
+ fields = type_struct_get_fields(type);
+ else
+- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
++ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
+ }
+ else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
+- fields = type_union_get_cases(type);
++ {
++ if (type_is_complete(type))
++ fields = type_union_get_cases(type);
++ else
++ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
++ }
+
+ if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
+- if (field->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 +2806,10 @@ 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 )
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
+ {
+- const type_t *type = arg->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 +2849,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 +2875,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);
+ }
+ }
+
+@@ -2837,6 +2941,7 @@ static void check_async_uuid(type_t *iface)
+ type_t *async_iface;
+ type_t *inherit;
+
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
+
+ inherit = iface->details.iface->inherit;
+@@ -2853,7 +2958,8 @@ 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;
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ args = func->declspec.type->details.function->args;
+ if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
+ {
+ if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
+@@ -2863,15 +2969,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));
+ }
+
+@@ -2911,6 +3017,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
+ static void check_all_user_types(const statement_list_t *stmts)
+ {
+ const statement_t *stmt;
++ const var_t *v;
+
+ if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
+ {
+@@ -2922,7 +3029,11 @@ 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;
+- check_for_additional_prototype_types(func->type->details.function->args);
++ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
++ if (func->declspec.type->details.function->args)
++ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
++ check_for_additional_prototype_types(v->declspec.type);
++ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
+ }
+ }
+ }
+@@ -2956,6 +3067,10 @@ static statement_t *make_statement_type_decl(type_t *type)
+ {
+ statement_t *stmt = make_statement(STMT_TYPE);
+ stmt->u.type = type;
++ if (type_is_defined(type))
++ {
++ stmt->declonly = FALSE;
++ }
+ return stmt;
+ }
+
+@@ -2970,16 +3085,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;
+ }
+@@ -3031,6 +3146,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ declarator_t *decl, *next;
+ statement_t *stmt;
+ type_list_t **type_list;
++ int defined = TRUE;
+
+ if (!decls) return NULL;
+
+@@ -3042,6 +3158,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ {
+ var_t *var = decl->var;
+ type_t *type = find_type_or_error(var->name, 0);
++
++ /* ensure that all of the types in this typedef statement have been defined
++ * before setting its declonly flag */
++ if (type_is_pointerish(type))
++ {
++ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
++ }
++ else
++ {
++ defined = defined & type_is_defined(type_get_real_type(type));
++ }
++
+ *type_list = xmalloc(sizeof(type_list_t));
+ (*type_list)->type = type;
+ (*type_list)->next = NULL;
+@@ -3051,6 +3179,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
+ free(var);
+ }
+
++ stmt->declonly = !defined;
+ return stmt;
+ }
+
+@@ -3091,7 +3220,7 @@ void init_loc_info(loc_info_t *i)
+
+ static void check_def(const type_t *t)
+ {
+- if (t->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type_is_defined(t))
++ error_loc("BAR %s: redefinition error; original definition was at %s:%d\n",
+ t->name, t->loc_info.input_name, t->loc_info.line_number);
+ }
+diff --git a/mingw-w64-tools/widl/src/parser.yy.c b/mingw-w64-tools/widl/src/parser.yy.c
+index 2aaf3c27..0482aa7e 100644
+--- a/mingw-w64-tools/widl/src/parser.yy.c
++++ b/mingw-w64-tools/widl/src/parser.yy.c
+@@ -1,6 +1,6 @@
+-#line 1 "parser.yy.c"
++#line 2 "parser.yy.c"
+
+-#line 3 "parser.yy.c"
++#line 4 "parser.yy.c"
+
+ #define YY_INT_ALIGNED short int
+
+@@ -1041,13 +1041,13 @@ UUID *parse_uuid(const char *u)
+ return uuid;
+ }
+
+-#line 1044 "parser.yy.c"
++#line 1045 "parser.yy.c"
+ /*
+ **************************************************************************
+ * The flexer starts here
+ **************************************************************************
+ */
+-#line 1050 "parser.yy.c"
++#line 1051 "parser.yy.c"
+
+ #define INITIAL 0
+ #define QUOTE 1
+@@ -1281,7 +1281,7 @@ YY_DECL
+ {
+ #line 132 "parser.l"
+
+-#line 1284 "parser.yy.c"
++#line 1285 "parser.yy.c"
+
+ while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
+ {
+@@ -1616,7 +1616,7 @@ YY_RULE_SETUP
+ #line 239 "parser.l"
+ ECHO;
+ YY_BREAK
+-#line 1619 "parser.yy.c"
++#line 1620 "parser.yy.c"
+
+ case YY_END_OF_BUFFER:
+ {
+diff --git a/mingw-w64-tools/widl/src/proxy.c b/mingw-w64-tools/widl/src/proxy.c
+index 87c27be9..36b552be 100644
+--- a/mingw-w64-tools/widl/src/proxy.c
++++ b/mingw-w64-tools/widl/src/proxy.c
+@@ -67,7 +67,7 @@ static void write_stubdesc(int expr_eval_routines)
+ print_proxy( "1, /* -error bounds_check flag */\n");
+ print_proxy( "0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_proxy( "0,\n");
+- print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_proxy( "0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_proxy( "0,\n");
+ print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_proxy( "0, /* notify & notify_flag routine table */\n");
+@@ -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_type(arg->declspec.type)) == TYPE_BASIC) continue;
++ if (type_get_type(type_pointer_get_ref_type(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_function_get_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_declspec_decl_left(proxy, &retval->declspec);
+ 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_declspec_decl_left(proxy, &retval->declspec);
+ 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_declspec_decl(proxy, &retval->declspec, 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_function_get_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_function_get_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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
++ fprintf(proxy, ", %s__frame->%s", is_array(arg->declspec.type) && !type_array_is_decl_as_ptr(arg->declspec.type) ? "*" :"" , arg->name);
+ }
+ fprintf(proxy, ");\n");
+ 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_function_get_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 );
+@@ -526,6 +526,7 @@ static int write_proxy_methods(type_t *iface, int skip)
+ if (skip || (is_local(func->attrs) && !get_callas_source(iface, func)))
+ print_proxy( "0, /* %s::%s */\n", iface->name, get_name(func));
+ else if (is_interpreted_func( iface, func ) &&
++ get_stub_mode() == MODE_Oif &&
+ !is_local( func->attrs ) &&
+ type_iface_get_inherit(iface))
+ print_proxy( "(void *)-1, /* %s::%s */\n", iface->name, get_name(func));
+@@ -613,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 = type_get_details(func->declspec.type)->function->idx;
+ if (cname) {
+ const statement_t *stmt2;
+ STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) {
+ const var_t *m = stmt2->u.var;
+ if (!strcmp(m->name, cname))
+ {
+- idx = m->type->details.function->idx;
++ idx = type_get_details(m->declspec.type)->function->idx;
+ break;
+ }
+ }
+@@ -738,7 +739,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
+ print_proxy( "{\n");
+ indent++;
+ print_proxy( "%s_%s\n",
+- iface->details.iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
++ type_get_details(iface)->iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
+ need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
+ indent--;
+ print_proxy( "}\n");
+@@ -839,8 +840,8 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
+ if (need_proxy(iface))
+ {
+ write_proxy(iface, proc_offset);
+- if (iface->details.iface->async_iface)
+- write_proxy(iface->details.iface->async_iface, proc_offset);
++ if (type_get_details(iface)->iface->async_iface)
++ write_proxy(type_get_details(iface)->iface->async_iface, proc_offset);
+ }
+ }
+ }
+@@ -869,9 +870,9 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
+ {
+ *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
+ (*ifaces)[(*count)++] = iface;
+- if (iface->details.iface->async_iface)
++ if (type_get_details(iface)->iface->async_iface)
+ {
+- iface = iface->details.iface->async_iface;
++ iface = type_get_details(iface)->iface->async_iface;
+ *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
+ (*ifaces)[(*count)++] = iface;
+ }
+@@ -942,7 +943,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
+ write_stubdesc(expr_eval_routines);
+
+ print_proxy( "#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32);
+- print_proxy( "#error Currently only Wine and WIN32 are supported.\n");
++ print_proxy( "#error Invalid build platform for this proxy.\n");
+ print_proxy( "#endif\n");
+ print_proxy( "\n");
+ write_procformatstring(proxy, stmts, need_proxy);
+@@ -1011,7 +1012,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
+ table_version = get_stub_mode() == MODE_Oif ? 2 : 1;
+ for (i = 0; i < count; i++)
+ {
+- if (interfaces[i]->details.iface->async_iface != interfaces[i]) continue;
++ if (type_get_details(interfaces[i])->iface->async_iface != interfaces[i]) continue;
+ if (table_version != 6)
+ {
+ fprintf(proxy, "static const IID *_AsyncInterfaceTable[] =\n");
+@@ -1053,26 +1054,6 @@ void write_proxies(const statement_list_t *stmts)
+ init_proxy(stmts);
+ if(!proxy) return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(proxy, "\n#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_proxy_routines( stmts );
+- fprintf(proxy, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_proxy_routines( stmts );
+- fprintf(proxy, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_proxy_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_proxy_routines( stmts );
+- }
+-
++ write_proxy_routines( stmts );
+ fclose(proxy);
+ }
+diff --git a/mingw-w64-tools/widl/src/register.c b/mingw-w64-tools/widl/src/register.c
+index 210fb747..1c369e7c 100644
+--- a/mingw-w64-tools/widl/src/register.c
++++ b/mingw-w64-tools/widl/src/register.c
+@@ -325,7 +325,7 @@ void output_typelib_regscript( const typelib_t *typelib )
+ sprintf(resname, "%s\\%d", typelib_name, expr->cval);
+ }
+ put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
+- lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part );
++ lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
+ put_str( indent, "FLAGS = s '%u'\n", flags );
+ put_str( --indent, "}\n" );
+ put_str( --indent, "}\n" );
+diff --git a/mingw-w64-tools/widl/src/server.c b/mingw-w64-tools/widl/src/server.c
+index 783ff900..dbed870a 100644
+--- a/mingw-w64-tools/widl/src/server.c
++++ b/mingw-w64-tools/widl/src/server.c
+@@ -55,6 +55,8 @@ 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 );
++ const decl_spec_t *ret_declspec = type_function_get_retdeclspec(func->declspec.type);
++ type_t *ret_type = ret_declspec->type;
+
+ if (is_interpreted_func( iface, func )) return;
+
+@@ -75,7 +77,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ indent++;
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE);
+
+ if (has_full_pointer)
+@@ -120,7 +122,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_function_get_args(func->declspec.type))
+ {
+ print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
+ indent++;
+@@ -154,35 +156,42 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ assign_stub_out_args(server, indent, func, "__frame->");
+
+ /* Call the real server function */
+- print_server("%s%s%s",
+- is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ",
+- prefix_server, get_name(func));
++ if (is_context_handle(ret_type))
++ {
++ print_server("__frame->_RetVal = NDRSContextUnmarshall((char*)0, _pRpcMessage->DataRepresentation);\n");
++ print_server("*((");
++ write_declspec_decl(server, ret_declspec, NULL);
++ fprintf(server, "*)NDRSContextValue(__frame->_RetVal)) = ");
++ }
++ else
++ 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_function_get_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_function_get_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_declspec_decl_left(server, &var->declspec);
+ 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");
+@@ -197,7 +206,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ {
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
+
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
+
+ print_server("_pRpcMessage->BufferLength = __frame->_StubMsg.BufferLength;\n");
+@@ -216,7 +225,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_MARSHAL);
+
+ /* marshall the return value */
+- if (!is_void(type_function_get_rettype(func->type)))
++ if (!is_void(ret_type))
+ write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
+
+ indent--;
+@@ -378,7 +387,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
+ print_server("1, /* -error bounds_check flag */\n");
+ print_server("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
+ print_server("0,\n");
+- print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
++ print_server("0x50200ca, /* MIDL Version 5.2.202 */\n");
+ print_server("0,\n");
+ print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
+ print_server("0, /* notify & notify_flag routine table */\n");
+@@ -544,26 +553,6 @@ void write_server(const statement_list_t *stmts)
+ if (!server)
+ return;
+
+- if (do_win32 && do_win64)
+- {
+- fprintf(server, "#ifndef _WIN64\n\n");
+- pointer_size = 4;
+- write_server_routines( stmts );
+- fprintf(server, "\n#else /* _WIN64 */\n\n");
+- pointer_size = 8;
+- write_server_routines( stmts );
+- fprintf(server, "\n#endif /* _WIN64 */\n");
+- }
+- else if (do_win32)
+- {
+- pointer_size = 4;
+- write_server_routines( stmts );
+- }
+- else if (do_win64)
+- {
+- pointer_size = 8;
+- write_server_routines( stmts );
+- }
+-
++ write_server_routines( stmts );
+ fclose(server);
+ }
+diff --git a/mingw-w64-tools/widl/src/typegen.c b/mingw-w64-tools/widl/src/typegen.c
+index 27ba60fc..eebb99f0 100644
+--- a/mingw-w64-tools/widl/src/typegen.c
++++ b/mingw-w64-tools/widl/src/typegen.c
+@@ -67,6 +67,7 @@ enum type_context
+ TYPE_CONTEXT_PARAM,
+ TYPE_CONTEXT_CONTAINER,
+ TYPE_CONTEXT_CONTAINER_NO_POINTERS,
++ TYPE_CONTEXT_RETVAL,
+ };
+
+ /* parameter flags in Oif mode */
+@@ -84,14 +85,14 @@ static const unsigned short IsSimpleRef = 0x0100;
+
+ static unsigned int field_memsize(const type_t *type, unsigned int *offset);
+ static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align);
+-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, unsigned int *typestring_offset);
+-static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
+-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec, const char *name, unsigned int *tfsoff);
++static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, int write_ptr, unsigned int *tfsoff);
+ static const var_t *find_array_or_string_in_struct(const type_t *type);
+ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, enum type_context context,
++ const decl_spec_t *declspec, enum type_context context,
+ const char *name, unsigned int *typestring_offset);
+ static unsigned int get_required_buffer_size_type( const type_t *type, const char *name,
+ const attr_list_t *attrs, int toplevel_param,
+@@ -196,7 +197,7 @@ static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr)
+ if (is_attr(t->attrs, attr))
+ return get_attrp(t->attrs, attr);
+ else if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else return NULL;
+ }
+ }
+@@ -266,7 +267,7 @@ unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int t
+ if (pointer_type)
+ return pointer_type;
+
+- for (t = type; type_is_alias(t); t = type_alias_get_aliasee(t))
++ for (t = type; type_is_alias(t); t = type_alias_get_aliasee_type(t))
+ {
+ pointer_type = get_attrv(t->attrs, ATTR_POINTERTYPE);
+ if (pointer_type)
+@@ -287,7 +288,7 @@ static unsigned char get_pointer_fc_context( const type_t *type, const attr_list
+ int pointer_fc = get_pointer_fc(type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM);
+
+ if (pointer_fc == FC_UP && is_attr( attrs, ATTR_OUT ) &&
+- context == TYPE_CONTEXT_PARAM && is_object( current_iface ))
++ (context == TYPE_CONTEXT_PARAM || context == TYPE_CONTEXT_RETVAL) && is_object( current_iface ))
+ pointer_fc = FC_OP;
+
+ return pointer_fc;
+@@ -315,7 +316,7 @@ static type_t *get_user_type(const type_t *t, const char **pname)
+ }
+
+ if (type_is_alias(t))
+- t = type_alias_get_aliasee(t);
++ t = type_alias_get_aliasee_type(t);
+ else
+ return NULL;
+ }
+@@ -350,10 +351,10 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
+ return TGT_RANGE;
+ return TGT_ENUM;
+ case TYPE_POINTER:
+- if (type_get_type(type_pointer_get_ref(type)) == TYPE_INTERFACE ||
+- (type_get_type(type_pointer_get_ref(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
++ if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
++ (type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
+ return TGT_IFACE_POINTER;
+- else if (is_aliaschain_attr(type_pointer_get_ref(type), ATTR_CONTEXTHANDLE))
++ else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
+ return TGT_CTXT_HANDLE_POINTER;
+ else
+ return TGT_POINTER;
+@@ -378,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:
+@@ -404,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);
+@@ -421,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:
+@@ -429,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:
+@@ -442,23 +443,27 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
+ }
+
+ static unsigned char get_contexthandle_flags( const type_t *iface, const attr_list_t *attrs,
+- const type_t *type )
++ const type_t *type, int is_return )
+ {
+ unsigned char flags = 0;
++ int is_out;
+
+ if (is_attr(iface->attrs, ATTR_STRICTCONTEXTHANDLE)) flags |= NDR_STRICT_CONTEXT_HANDLE;
+
+ if (is_ptr(type) &&
+ !is_attr( type->attrs, ATTR_CONTEXTHANDLE ) &&
+ !is_attr( attrs, ATTR_CONTEXTHANDLE ))
+- flags |= 0x80;
++ flags |= HANDLE_PARAM_IS_VIA_PTR;
+
+- if (is_attr(attrs, ATTR_IN))
++ if (is_return) return flags | HANDLE_PARAM_IS_OUT | HANDLE_PARAM_IS_RETURN;
++
++ is_out = is_attr(attrs, ATTR_OUT);
++ if (is_attr(attrs, ATTR_IN) || !is_out)
+ {
+- flags |= 0x40;
+- if (!is_attr(attrs, ATTR_OUT)) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
++ flags |= HANDLE_PARAM_IS_IN;
++ if (!is_out) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
+ }
+- if (is_attr(attrs, ATTR_OUT)) flags |= 0x20;
++ if (is_out) flags |= HANDLE_PARAM_IS_OUT;
+
+ return flags;
+ }
+@@ -490,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;
+@@ -505,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_type(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))
+@@ -518,7 +523,7 @@ unsigned char get_struct_fc(const type_t *type)
+ if (type_array_has_variance(t))
+ has_variance = 1;
+
+- t = type_array_get_element(t);
++ t = type_array_get_element_type(t);
+ typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
+ }
+
+@@ -620,7 +625,7 @@ static unsigned char get_array_fc(const type_t *type)
+ const expr_t *size_is;
+ const type_t *elem_type;
+
+- elem_type = type_array_get_element(type);
++ elem_type = type_array_get_element_type(type);
+ size_is = type_array_get_conformance(type);
+
+ if (!size_is)
+@@ -709,14 +714,14 @@ static int type_has_pointers(const type_t *type)
+ case TGT_POINTER:
+ return TRUE;
+ case TGT_ARRAY:
+- return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element(type));
++ return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element_type(type));
+ case TGT_STRUCT:
+ {
+ var_list_t *fields = type_struct_get_fields(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;
+@@ -728,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;
+@@ -763,14 +768,14 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
+ if (get_pointer_fc(type, attrs, toplevel_param) == FC_FP)
+ return TRUE;
+ else
+- return type_has_full_pointer(type_array_get_element(type), NULL, FALSE);
++ return type_has_full_pointer(type_array_get_element_type(type), NULL, FALSE);
+ case TGT_STRUCT:
+ {
+ var_list_t *fields = type_struct_get_fields(type);
+ 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;
+@@ -782,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;
+@@ -852,7 +857,7 @@ static const char *get_context_handle_type_name(const type_t *type)
+ const type_t *t;
+ for (t = type;
+ is_ptr(t) || type_is_alias(t);
+- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
++ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
+ if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+ return t->name;
+ assert(0);
+@@ -902,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
++ write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
+
+ fprintf(file, "\n");
+ }
+@@ -975,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 */
+@@ -991,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;
+@@ -1006,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) && type_get_details(var->declspec.type)->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;
+ }
+@@ -1031,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_type( var->declspec.type );
+
+ if (!is_string_type( var->attrs, ref ))
+ buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment );
+@@ -1059,11 +1064,19 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
+ case TGT_UNION:
+ case TGT_USER_TYPE:
+ case TGT_RANGE:
+- case TGT_ARRAY:
+- *flags |= IsSimpleRef | MustFree;
++ *flags |= MustFree | IsSimpleRef;
+ *typestring_offset = ref->typestring_offset;
+ if (!is_in && is_out) server_size = type_memsize( ref );
+ break;
++ case TGT_ARRAY:
++ *flags |= MustFree;
++ if (!type_array_is_decl_as_ptr(ref))
++ {
++ *flags |= IsSimpleRef;
++ *typestring_offset = ref->typestring_offset;
++ }
++ if (!is_in && is_out) server_size = type_memsize( ref );
++ break;
+ case TGT_STRING:
+ case TGT_POINTER:
+ case TGT_CTXT_HANDLE:
+@@ -1115,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_function_get_args( func->declspec.type );
++ var_t *retval = type_function_get_retval( func->declspec.type );
+ unsigned char oi2_flags = 0x40; /* HasExtensions */
+ unsigned short flags;
+ unsigned int stack_size, typestring_offset;
+@@ -1131,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 );
+@@ -1185,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;
+
+@@ -1195,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;
+@@ -1215,10 +1228,12 @@ 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) &&
++ type_get_details(var->declspec.type)->array.ptr_tfsoff)
++ {
++ offset = var->declspec.type->typestring_offset;
++ }
+
+ if (is_return)
+ print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
+@@ -1241,8 +1256,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_function_get_args( func->declspec.type );
++ const type_t *ret_type = type_function_get_rettype( func->declspec.type );
+
+ if (type_get_type( ret_type ) == TYPE_BASIC)
+ {
+@@ -1264,10 +1279,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;
+@@ -1292,7 +1307,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+ unsigned short num_proc )
+ {
+ var_t *var;
+- var_list_t *args = type_get_function_args( func->type );
++ var_list_t *args = type_function_get_args( func->declspec.type );
+ unsigned char explicit_fc, implicit_fc;
+ unsigned char handle_flags;
+ const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
+@@ -1323,7 +1338,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++;
+@@ -1351,22 +1366,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 );
++ 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;
+@@ -1381,7 +1396,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
+
+ if (is_attr( func->attrs, ATTR_NOTIFY )) ext_flags |= 0x08; /* HasNotify */
+ if (is_attr( func->attrs, ATTR_NOTIFYFLAG )) ext_flags |= 0x10; /* HasNotify2 */
+- if (iface == iface->details.iface->async_iface) oi2_flags |= 0x20;
++ if (iface == type_get_const_details(iface)->iface->async_iface) oi2_flags |= 0x20;
+
+ size = get_function_buffer_size( func, PASS_IN );
+ print_file( file, indent, "NdrFcShort(0x%x),\t/* client buffer = %u */\n", size, size );
+@@ -1402,9 +1417,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;
+@@ -1427,15 +1442,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
+ if (is_new_style)
+@@ -1446,7 +1461,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)
+ {
+@@ -1475,13 +1490,13 @@ static void for_each_iface(const statement_list_t *stmts,
+
+ if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+ {
+- if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE)
++ if (stmt->type != STMT_TYPE || type_get_type_detect_alias(stmt->u.type) != TYPE_INTERFACE)
+ continue;
+ iface = stmt->u.type;
+ if (!pred(iface)) continue;
+ proc(iface, file, indent, offset);
+- if (iface->details.iface->async_iface)
+- proc(iface->details.iface->async_iface, file, indent, offset);
++ if (type_get_const_details(iface)->iface->async_iface)
++ proc(type_get_const_details(iface)->iface->async_iface, file, indent, offset);
+ }
+ }
+
+@@ -1593,7 +1608,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;
+ }
+@@ -1656,7 +1671,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
+
+ if (type_get_type(cont_type) == TYPE_FUNCTION)
+ {
+- var_list_t *args = type_get_function_args( cont_type );
++ var_list_t *args = type_function_get_args( cont_type );
+
+ if (is_object( iface )) offset += pointer_size;
+ if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
+@@ -1664,7 +1679,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 );
+@@ -1676,11 +1691,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;
+@@ -1819,7 +1834,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);
+@@ -1841,9 +1856,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;
+ }
+@@ -1931,12 +1946,12 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
+ {
+ if (is_conformant_array(t))
+ {
+- type_memsize_and_alignment(type_array_get_element(t), align);
++ type_memsize_and_alignment(type_array_get_element_type(t), align);
+ size = 0;
+ }
+ else
+ size = type_array_get_dim(t) *
+- type_memsize_and_alignment(type_array_get_element(t), align);
++ type_memsize_and_alignment(type_array_get_element_type(t), align);
+ }
+ else /* declared as a pointer */
+ {
+@@ -2016,8 +2031,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;
+@@ -2025,8 +2040,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;
+@@ -2034,14 +2049,14 @@ 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;
+ case TYPE_ARRAY:
+ if (!type_array_is_decl_as_ptr(t))
+- return type_buffer_alignment( type_array_get_element(t) );
++ return type_buffer_alignment( type_array_get_element_type(t) );
+ /* else fall through */
+ case TYPE_POINTER:
+ return 4;
+@@ -2064,12 +2079,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
++ if (type_has_full_pointer( var->declspec.type, var->attrs, TRUE ))
+ return TRUE;
+ return FALSE;
+ }
+@@ -2114,12 +2129,13 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
+ {
+ if (context == TYPE_CONTEXT_TOPLEVELPARAM && is_ptr(type) && pointer_type == FC_RP)
+ {
+- switch (typegen_detect_type(type_pointer_get_ref(type), NULL, TDT_ALL_TYPES))
++ switch (typegen_detect_type(type_pointer_get_ref_type(type), NULL, TDT_ALL_TYPES))
+ {
+ case TGT_STRING:
+ case TGT_POINTER:
+ case TGT_CTXT_HANDLE:
+ case TGT_CTXT_HANDLE_POINTER:
++ case TGT_ARRAY:
+ flags |= FC_ALLOCED_ON_STACK;
+ break;
+ case TGT_IFACE_POINTER:
+@@ -2134,7 +2150,7 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
+
+ if (is_ptr(type))
+ {
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *ref = type_pointer_get_ref_type(type);
+ if(is_declptr(ref) && !is_user_type(ref))
+ flags |= FC_POINTER_DEREF;
+ }
+@@ -2175,7 +2191,7 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
+
+ pointer_fc = get_pointer_fc_context(type, attrs, context);
+
+- ref = type_pointer_get_ref(type);
++ ref = type_pointer_get_ref_type(type);
+ if (type_get_type(ref) == TYPE_ENUM)
+ fc = get_enum_fc(ref);
+ else
+@@ -2200,22 +2216,23 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
+ return 4;
+ }
+
+-static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff)
++static void print_start_tfs_comment(FILE *file, const decl_spec_t *ds, unsigned int tfsoff)
+ {
+ print_file(file, 0, "/* %u (", tfsoff);
+- write_type_decl(file, t, NULL);
++ write_declspec_decl(file, ds, NULL);
+ print_file(file, 0, ") */\n");
+ }
+
+ static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, unsigned int ref_offset,
++ const decl_spec_t *declspec, unsigned int ref_offset,
+ enum type_context context,
+ unsigned int *typestring_offset)
+ {
+ unsigned int offset = *typestring_offset;
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *type = declspec->type;
++ type_t *ref = type_pointer_get_ref_type(type);
+
+- print_start_tfs_comment(file, type, offset);
++ print_start_tfs_comment(file, declspec, offset);
+ update_tfsoff(type, offset, file);
+
+ switch (typegen_detect_type(ref, attrs, TDT_ALL_TYPES))
+@@ -2258,10 +2275,11 @@ static int user_type_has_variable_size(const type_t *t)
+ return FALSE;
+ }
+
+-static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
++static unsigned int write_user_tfs(FILE *file, const decl_spec_t *declspec, unsigned int *tfsoff)
+ {
+ unsigned int start, absoff, flags;
+ const char *name = NULL;
++ type_t *type = declspec->type;
+ type_t *utype = get_user_type(type, &name);
+ unsigned int usize = type_memsize(utype);
+ unsigned int ualign = type_buffer_alignment(utype);
+@@ -2279,6 +2297,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ type_get_type(utype) == TYPE_ENUM)
+ {
+ unsigned char fc;
++ decl_spec_t ds;
+
+ if (type_get_type(utype) == TYPE_ENUM)
+ fc = get_enum_fc(utype);
+@@ -2286,7 +2305,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ fc = get_basic_fc(utype);
+
+ absoff = *tfsoff;
+- print_start_tfs_comment(file, utype, absoff);
++ print_start_tfs_comment(file, init_declspec(&ds, utype), absoff);
+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
+ *tfsoff += 2;
+@@ -2294,7 +2313,10 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+ else
+ {
+ if (!processed(utype))
+- write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff);
++ {
++ decl_spec_t ds;
++ write_embedded_types(file, NULL, init_declspec(&ds, utype), utype->name, TRUE, tfsoff);
++ }
+ absoff = utype->typestring_offset;
+ }
+
+@@ -2307,7 +2329,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
+
+ start = *tfsoff;
+ update_tfsoff(type, start, file);
+- print_start_tfs_comment(file, type, start);
++ print_start_tfs_comment(file, declspec, start);
+ print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", FC_USER_MARSHAL);
+ print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
+ flags | (ualign - 1), ualign - 1, flags);
+@@ -2364,11 +2386,12 @@ static void write_member_type(FILE *file, const type_t *cont,
+ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const type_t *type,
+ int cont_is_complex, unsigned int *tfsoff)
+ {
+- type_t *elem = type_array_get_element(type);
++ const decl_spec_t *element = type_array_get_element(type);
++ type_t *elem = element->type;
+
+ if (!is_embedded_complex(elem) && is_ptr(elem))
+ {
+- type_t *ref = type_pointer_get_ref(elem);
++ type_t *ref = type_pointer_get_ref_type(elem);
+
+ if (processed(ref))
+ {
+@@ -2378,7 +2401,7 @@ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const
+ }
+ if (cont_is_complex && is_string_type(attrs, elem))
+ {
+- write_string_tfs(file, NULL, elem, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
++ write_string_tfs(file, NULL, element, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
+ return;
+ }
+ if (!is_string_type(NULL, elem) &&
+@@ -2410,7 +2433,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))
+ {
+@@ -2433,13 +2456,14 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
+ }
+
+ static int write_pointer_description_offsets(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int written = 0;
+
+- if ((is_ptr(type) && type_get_type(type_pointer_get_ref(type)) != TYPE_INTERFACE) ||
++ if ((is_ptr(type) && type_get_type(type_pointer_get_ref_type(type)) != TYPE_INTERFACE) ||
+ (is_array(type) && type_array_is_decl_as_ptr(type)))
+ {
+ if (offset_in_memory && offset_in_buffer)
+@@ -2464,10 +2488,10 @@ static int write_pointer_description_offsets(
+
+ if (is_ptr(type))
+ {
+- type_t *ref = type_pointer_get_ref(type);
++ type_t *ref = type_pointer_get_ref_type(type);
+
+ if (is_string_type(attrs, type))
+- write_string_tfs(file, attrs, type, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
++ write_string_tfs(file, attrs, declspec, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
+ else if (processed(ref))
+ write_nonsimple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER,
+ ref->typestring_offset, typestring_offset);
+@@ -2505,13 +2529,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, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2531,10 +2555,11 @@ static int write_pointer_description_offsets(
+ }
+
+ static int write_no_repeat_pointer_descriptions(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int written = 0;
+
+ if (is_ptr(type) ||
+@@ -2544,7 +2569,7 @@ static int write_no_repeat_pointer_descriptions(
+ print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
+ *typestring_offset += 2;
+
+- return write_pointer_description_offsets(file, attrs, type,
++ return write_pointer_description_offsets(file, attrs, declspec,
+ offset_in_memory, offset_in_buffer, typestring_offset);
+ }
+
+@@ -2557,13 +2582,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,
+ offset_in_memory, offset_in_buffer, typestring_offset);
+ }
+ }
+@@ -2582,10 +2607,11 @@ static int write_no_repeat_pointer_descriptions(
+ /* Note: if file is NULL return value is number of pointers to write, else
+ * it is the number of type format characters written */
+ static int write_fixed_array_pointer_descriptions(
+- FILE *file, const attr_list_t *attrs, type_t *type,
++ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ int pointer_count = 0;
+
+ if (type_get_type(type) == TYPE_ARRAY &&
+@@ -2602,7 +2628,7 @@ static int write_fixed_array_pointer_descriptions(
+ unsigned int offset_of_array_pointer_mem = 0;
+ unsigned int offset_of_array_pointer_buf = 0;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", FC_FIXED_REPEAT);
+ print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
+@@ -2613,7 +2639,7 @@ static int write_fixed_array_pointer_descriptions(
+ *typestring_offset += 10;
+
+ pointer_count = write_pointer_description_offsets(
+- file, attrs, type, &offset_of_array_pointer_mem,
++ file, attrs, declspec, &offset_of_array_pointer_mem,
+ &offset_of_array_pointer_buf, typestring_offset);
+ }
+ }
+@@ -2626,13 +2652,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, offset_in_memory, offset_in_buffer,
+ typestring_offset);
+ }
+ }
+@@ -2673,7 +2699,7 @@ static int write_conformant_array_pointer_descriptions(
+ unsigned int offset_of_array_pointer_mem = offset_in_memory;
+ unsigned int offset_of_array_pointer_buf = offset_in_memory;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ if (increment_size > USHRT_MAX)
+ error("array size of %u bytes is too large\n", increment_size);
+@@ -2715,7 +2741,7 @@ static int write_varying_array_pointer_descriptions(
+ {
+ unsigned int increment_size;
+
+- increment_size = type_memsize(type_array_get_element(type));
++ increment_size = type_memsize(type_array_get_element_type(type));
+
+ if (increment_size > USHRT_MAX)
+ error("array size of %u bytes is too large\n", increment_size);
+@@ -2741,20 +2767,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);
+ }
+ }
+@@ -2773,9 +2799,10 @@ static int write_varying_array_pointer_descriptions(
+ return pointer_count;
+ }
+
+-static void write_pointer_description(FILE *file, const attr_list_t *attrs, type_t *type,
++static void write_pointer_description(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int offset_in_buffer;
+ unsigned int offset_in_memory;
+
+@@ -2786,7 +2813,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ offset_in_memory = 0;
+ offset_in_buffer = 0;
+ write_no_repeat_pointer_descriptions(
+- file, NULL, type,
++ file, NULL, declspec,
+ &offset_in_memory, &offset_in_buffer, typestring_offset);
+ }
+
+@@ -2794,7 +2821,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ offset_in_memory = 0;
+ offset_in_buffer = 0;
+ write_fixed_array_pointer_descriptions(
+- file, NULL, type,
++ file, NULL, declspec,
+ &offset_in_memory, &offset_in_buffer, typestring_offset);
+
+ /* pass 3: search for pointers in conformant only arrays (but don't descend
+@@ -2806,7 +2833,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);
+ }
+@@ -2820,9 +2847,10 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
+ }
+
+ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, enum type_context context,
++ const decl_spec_t *declspec, enum type_context context,
+ const char *name, unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int start_offset;
+ unsigned char rtype;
+ type_t *elem_type;
+@@ -2836,7 +2864,7 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ int pointer_type = get_pointer_fc_context(type, attrs, context);
+ if (!pointer_type)
+ pointer_type = FC_RP;
+- print_start_tfs_comment(file, type, *typestring_offset);
++ print_start_tfs_comment(file, declspec, *typestring_offset);
+ print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
+ pointer_type, flag, string_of_type(pointer_type),
+ flag ? " [simple_pointer]" : "");
+@@ -2850,12 +2878,12 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ }
+
+ if (is_array(type))
+- elem_type = type_array_get_element(type);
++ elem_type = type_array_get_element_type(type);
+ else
+- elem_type = type_pointer_get_ref(type);
++ elem_type = type_pointer_get_ref_type(type);
+
+ if (type_get_type(elem_type) == TYPE_POINTER && is_array(type))
+- return write_array_tfs(file, attrs, type, name, typestring_offset);
++ return write_array_tfs(file, attrs, declspec, name, typestring_offset);
+
+ if (type_get_type(elem_type) != TYPE_BASIC)
+ {
+@@ -2929,34 +2957,31 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
+ }
+ }
+
+-static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, unsigned int *typestring_offset)
+ {
++ type_t *type = declspec->type;
+ const expr_t *length_is = type_array_get_variance(type);
+ const expr_t *size_is = type_array_get_conformance(type);
+ unsigned int align;
+ unsigned int size;
+ unsigned int start_offset;
+ unsigned char fc;
+- int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
+ unsigned int baseoff
+ = !type_array_is_decl_as_ptr(type) && current_structure
+ ? type_memsize(current_structure)
+ : 0;
+
+- if (!pointer_type)
+- pointer_type = FC_RP;
+-
+- if (!is_string_type(attrs, type_array_get_element(type)))
++ if (!is_string_type(attrs, type_array_get_element_type(type)))
+ write_embedded_types(file, attrs, type_array_get_element(type), name, FALSE, typestring_offset);
+
+- size = type_memsize(is_conformant_array(type) ? type_array_get_element(type) : type);
+- align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element(type) : type);
++ size = type_memsize(is_conformant_array(type) ? type_array_get_element_type(type) : type);
++ align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element_type(type) : type);
+ fc = get_array_fc(type);
+
+ start_offset = *typestring_offset;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
+ *typestring_offset += 2;
+@@ -2982,7 +3007,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
+
+ if (fc == FC_SMVARRAY || fc == FC_LGVARRAY)
+ {
+- unsigned int elsize = type_memsize(type_array_get_element(type));
++ unsigned int elsize = type_memsize(type_array_get_element_type(type));
+ unsigned int dim = type_array_get_dim(type);
+
+ if (fc == FC_LGVARRAY)
+@@ -3005,13 +3030,13 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
+ += write_conf_or_var_desc(file, current_structure, baseoff,
+ type, length_is);
+
+- if (type_has_pointers(type_array_get_element(type)) &&
++ if (type_has_pointers(type_array_get_element_type(type)) &&
+ (type_array_is_decl_as_ptr(type) || !current_structure))
+ {
+ print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
+ print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *typestring_offset += 2;
+- write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, type, typestring_offset);
++ write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, declspec, typestring_offset);
+ print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
+ *typestring_offset += 1;
+ }
+@@ -3048,7 +3073,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;
+@@ -3071,7 +3096,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);
+@@ -3100,7 +3125,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;
+ }
+@@ -3118,9 +3143,10 @@ static void write_struct_members(FILE *file, const type_t *type,
+ write_end(file, typestring_offset);
+ }
+
+-static unsigned int write_struct_tfs(FILE *file, type_t *type,
++static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec,
+ const char *name, unsigned int *tfsoff)
+ {
++ type_t *type = declspec->type;
+ const type_t *save_current_structure = current_structure;
+ unsigned int total_size;
+ const var_t *array;
+@@ -3143,15 +3169,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, 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_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, array->name, tfsoff);
+ }
+
+ corroff = *tfsoff;
+@@ -3159,7 +3185,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+
+ start_offset = *tfsoff;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
+ print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
+ print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)total_size, total_size);
+@@ -3167,7 +3193,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);
+@@ -3198,7 +3224,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
+ print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
+ print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
+ *tfsoff += 2;
+- write_pointer_description(file, NULL, type, tfsoff);
++ write_pointer_description(file, NULL, declspec, tfsoff);
+ print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
+ *tfsoff += 1;
+ }
+@@ -3213,15 +3239,16 @@ 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;
++ const decl_spec_t *fds = &f->declspec;
++ type_t *ft = fds->type;
+ switch (typegen_detect_type(ft, f->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_POINTER:
+ if (is_string_type(f->attrs, ft))
+- write_string_tfs(file, f->attrs, ft, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
++ write_string_tfs(file, f->attrs, fds, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
+ else
+- write_pointer_tfs(file, f->attrs, ft,
+- type_pointer_get_ref(ft)->typestring_offset,
++ write_pointer_tfs(file, f->attrs, fds,
++ type_pointer_get_ref_type(ft)->typestring_offset,
+ TYPE_CONTEXT_CONTAINER, tfsoff);
+ break;
+ case TGT_ARRAY:
+@@ -3283,8 +3310,9 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
+ }
+
+ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+- type_t *type, unsigned int *tfsoff)
++ const decl_spec_t *declspec, unsigned int *tfsoff)
+ {
++ type_t* type = declspec->type;
+ unsigned int start_offset;
+ unsigned int size;
+ var_list_t *fields;
+@@ -3309,17 +3337,17 @@ 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, f->name, TRUE, tfsoff);
+ }
+
+ start_offset = *tfsoff;
+ update_tfsoff(type, start_offset, file);
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ 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;
+
+@@ -3351,8 +3379,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);
+@@ -3407,7 +3435,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;
+@@ -3448,16 +3476,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
+ return start_offset;
+ }
+
+-static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
++static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ unsigned int *typeformat_offset)
+ {
+ unsigned int i;
++ type_t *type = declspec->type;
+ unsigned int start_offset = *typeformat_offset;
+ expr_t *iid = get_attrp(attrs, ATTR_IIDIS);
+
+ if (!iid && processed(type)) return type->typestring_offset;
+
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+ update_tfsoff(type, start_offset, file);
+
+ if (iid)
+@@ -3469,7 +3498,7 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
+ }
+ else
+ {
+- const type_t *base = is_ptr(type) ? type_pointer_get_ref(type) : type;
++ const type_t *base = is_ptr(type) ? type_pointer_get_ref_type(type) : type;
+ const UUID *uuid = get_attrp(base->attrs, ATTR_UUID);
+
+ if (! uuid)
+@@ -3493,18 +3522,19 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
+
+ static unsigned int write_contexthandle_tfs(FILE *file,
+ const attr_list_t *attrs,
+- type_t *type,
+- int toplevel_param,
++ const decl_spec_t *declspec,
++ enum type_context context,
+ unsigned int *typeformat_offset)
+ {
++ type_t *type = declspec->type;
+ unsigned int start_offset = *typeformat_offset;
+- unsigned char flags = get_contexthandle_flags( current_iface, attrs, type );
++ unsigned char flags = get_contexthandle_flags( current_iface, attrs, type, context == TYPE_CONTEXT_RETVAL );
+
+- print_start_tfs_comment(file, type, start_offset);
++ print_start_tfs_comment(file, declspec, start_offset);
+
+ if (flags & 0x80) /* via ptr */
+ {
+- int pointer_type = get_pointer_fc( type, attrs, toplevel_param );
++ int pointer_type = get_pointer_fc( type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM );
+ if (!pointer_type) pointer_type = FC_RP;
+ *typeformat_offset += 4;
+ print_file(file, 2,"0x%x, 0x0,\t/* %s */\n", pointer_type, string_of_type(pointer_type) );
+@@ -3514,8 +3544,7 @@ static unsigned int write_contexthandle_tfs(FILE *file,
+
+ print_file(file, 2, "0x%02x,\t/* FC_BIND_CONTEXT */\n", FC_BIND_CONTEXT);
+ print_file(file, 2, "0x%x,\t/* Context flags: ", flags);
+- /* return and can't be null values overlap */
+- if (((flags & 0x21) != 0x21) && (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL))
++ if (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL)
+ print_file(file, 0, "can't be null, ");
+ if (flags & NDR_CONTEXT_HANDLE_SERIALIZE)
+ print_file(file, 0, "serialize, ");
+@@ -3523,13 +3552,13 @@ static unsigned int write_contexthandle_tfs(FILE *file,
+ print_file(file, 0, "no serialize, ");
+ if (flags & NDR_STRICT_CONTEXT_HANDLE)
+ print_file(file, 0, "strict, ");
+- if ((flags & 0x21) == 0x20)
+- print_file(file, 0, "out, ");
+- if ((flags & 0x21) == 0x21)
++ if (flags & HANDLE_PARAM_IS_RETURN)
+ print_file(file, 0, "return, ");
+- if (flags & 0x40)
++ if (flags & HANDLE_PARAM_IS_OUT)
++ print_file(file, 0, "out, ");
++ if (flags & HANDLE_PARAM_IS_IN)
+ print_file(file, 0, "in, ");
+- if (flags & 0x80)
++ if (flags & HANDLE_PARAM_IS_VIA_PTR)
+ print_file(file, 0, "via ptr, ");
+ print_file(file, 0, "*/\n");
+ print_file(file, 2, "0x%x,\t/* rundown routine */\n", get_context_handle_offset( type ));
+@@ -3568,24 +3597,23 @@ static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs,
+ return start_offset;
+ }
+
+-static unsigned int write_type_tfs(FILE *file, int indent,
+- const attr_list_t *attrs, type_t *type,
+- const char *name,
++static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
++ const decl_spec_t *declspec, const char *name,
+ enum type_context context,
+ unsigned int *typeformat_offset)
+ {
+ unsigned int offset;
++ type_t *type = declspec->type;
+
+ switch (typegen_detect_type(type, attrs, TDT_ALL_TYPES))
+ {
+ case TGT_CTXT_HANDLE:
+ case TGT_CTXT_HANDLE_POINTER:
+- return write_contexthandle_tfs(file, attrs, type,
+- context == TYPE_CONTEXT_TOPLEVELPARAM, typeformat_offset);
++ return write_contexthandle_tfs(file, attrs, declspec, context, typeformat_offset);
+ case TGT_USER_TYPE:
+- return write_user_tfs(file, type, typeformat_offset);
++ return write_user_tfs(file, declspec, typeformat_offset);
+ case TGT_STRING:
+- return write_string_tfs(file, attrs, type, context, name, typeformat_offset);
++ return write_string_tfs(file, attrs, declspec, context, name, typeformat_offset);
+ case TGT_ARRAY:
+ {
+ unsigned int off;
+@@ -3593,15 +3621,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ if ((context != TYPE_CONTEXT_CONTAINER &&
+ context != TYPE_CONTEXT_CONTAINER_NO_POINTERS) ||
+ !is_conformant_array(type) || type_array_is_decl_as_ptr(type))
+- off = write_array_tfs(file, attrs, type, name, typeformat_offset);
++ off = write_array_tfs(file, attrs, declspec, name, typeformat_offset);
+ else
+ off = 0;
+ if (context != TYPE_CONTEXT_CONTAINER &&
+ context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ {
+ int ptr_type;
+- ptr_type = get_pointer_fc(type, attrs,
+- context == TYPE_CONTEXT_TOPLEVELPARAM);
++ ptr_type = get_pointer_fc_context(type, attrs, context);
+ if (ptr_type != FC_RP || type_array_is_decl_as_ptr(type))
+ {
+ unsigned int absoff = type->typestring_offset;
+@@ -3615,14 +3642,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ if (ptr_type != FC_RP) update_tfsoff( type, off, file );
+ *typeformat_offset += 4;
+ }
+- type->details.array.ptr_tfsoff = off;
++ type_get_details(type)->array.ptr_tfsoff = off;
+ }
+ return off;
+ }
+ case TGT_STRUCT:
+- return write_struct_tfs(file, type, name, typeformat_offset);
++ return write_struct_tfs(file, declspec, name, typeformat_offset);
+ case TGT_UNION:
+- return write_union_tfs(file, attrs, type, typeformat_offset);
++ return write_union_tfs(file, attrs, declspec, typeformat_offset);
+ case TGT_ENUM:
+ case TGT_BASIC:
+ /* nothing to do */
+@@ -3635,11 +3662,11 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ return write_range_tfs(file, attrs, type, range_list, typeformat_offset);
+ }
+ case TGT_IFACE_POINTER:
+- return write_ip_tfs(file, attrs, type, typeformat_offset);
++ return write_ip_tfs(file, attrs, declspec, typeformat_offset);
+ case TGT_POINTER:
+ {
+ enum type_context ref_context;
+- type_t *ref = type_pointer_get_ref(type);
++ const decl_spec_t *ref = type_pointer_get_ref(type);
+
+ if (context == TYPE_CONTEXT_TOPLEVELPARAM)
+ ref_context = TYPE_CONTEXT_PARAM;
+@@ -3648,22 +3675,22 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ else
+ ref_context = context;
+
+- if (is_string_type(attrs, ref))
++ if (is_string_type(attrs, ref->type))
+ {
+ if (context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+- write_pointer_tfs(file, attrs, type, *typeformat_offset + 4, context, typeformat_offset);
++ write_pointer_tfs(file, attrs, declspec, *typeformat_offset + 4, context, typeformat_offset);
+
+- offset = write_type_tfs(file, indent, attrs, ref, name, ref_context, typeformat_offset);
++ offset = write_type_tfs(file, attrs, ref, name, ref_context, typeformat_offset);
+ if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ return 0;
+ return offset;
+ }
+
+- offset = write_type_tfs( file, indent, attrs, type_pointer_get_ref(type), name,
++ offset = write_type_tfs( file, attrs, type_pointer_get_ref(type), name,
+ ref_context, typeformat_offset);
+ if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
+ return 0;
+- return write_pointer_tfs(file, attrs, type, offset, context, typeformat_offset);
++ return write_pointer_tfs(file, attrs, declspec, offset, context, typeformat_offset);
+ }
+ case TGT_INVALID:
+ break;
+@@ -3672,10 +3699,10 @@ static unsigned int write_type_tfs(FILE *file, int indent,
+ return 0;
+ }
+
+-static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
++static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
+ const char *name, int write_ptr, unsigned int *tfsoff)
+ {
+- return write_type_tfs(file, 2, attrs, type, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
++ return write_type_tfs(file, attrs, declspec, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
+ }
+
+ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned int *offset)
+@@ -3693,21 +3720,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, 2, func->attrs, var->type, func->name,
+- TYPE_CONTEXT_PARAM, offset);
++ 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, 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, 2, var->attrs, var->type, var->name,
++ if (type_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), var_t, entry )
++ var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, var->name,
+ TYPE_CONTEXT_TOPLEVELPARAM, offset );
+ break;
+
+@@ -3719,9 +3746,12 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
+ {
+ if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
+ || is_attr(type_entry->type->attrs, ATTR_DECODE))
+- type_entry->type->typestring_offset = write_type_tfs( file, 2,
+- type_entry->type->attrs, type_entry->type, type_entry->type->name,
++ {
++ decl_spec_t ds;
++ type_entry->type->typestring_offset = write_type_tfs( file,
++ type_entry->type->attrs, init_declspec(&ds, type_entry->type), type_entry->type->name,
+ TYPE_CONTEXT_CONTAINER, offset);
++ }
+ }
+ break;
+ }
+@@ -3842,7 +3872,7 @@ static unsigned int get_required_buffer_size_type(
+ case TGT_POINTER:
+ {
+ unsigned int size, align;
+- const type_t *ref = type_pointer_get_ref(type);
++ const type_t *ref = type_pointer_get_ref_type(type);
+ if (is_string_type( attrs, ref )) break;
+ if (!(size = get_required_buffer_size_type( ref, name, NULL, FALSE, &align ))) break;
+ if (get_pointer_fc(type, attrs, toplevel_param) != FC_RP)
+@@ -3862,7 +3892,7 @@ static unsigned int get_required_buffer_size_type(
+ case FC_SMFARRAY:
+ case FC_LGFARRAY:
+ return type_array_get_dim(type) *
+- get_required_buffer_size_type(type_array_get_element(type), name,
++ get_required_buffer_size_type(type_array_get_element_type(type), name,
+ NULL, FALSE, alignment);
+ }
+ }
+@@ -3893,8 +3923,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;
+@@ -3905,19 +3935,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_function_get_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_function_get_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;
+ }
+@@ -3953,9 +3983,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) ? "," : ");");
+@@ -3968,7 +3998,8 @@ 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;
++ const decl_spec_t *declspec = &var->declspec;
++ type_t *type = declspec->type;
+ unsigned int alignment = 0;
+
+ /* no work to do for other phases, buffer sizing is done elsewhere */
+@@ -3999,8 +4030,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ }
+ else
+ {
+- const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type;
+- switch (get_basic_fc(ref))
++ const decl_spec_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : declspec;
++ switch (get_basic_fc(ref->type))
+ {
+ case FC_BYTE:
+ case FC_CHAR:
+@@ -4037,7 +4068,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+
+ default:
+ error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n",
+- var->name, get_basic_fc(ref));
++ var->name, get_basic_fc(ref->type));
+ }
+
+ if (phase == PHASE_MARSHAL && alignment > 1)
+@@ -4048,7 +4079,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ if (phase == PHASE_MARSHAL)
+ {
+ print_file(file, indent, "*(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ if (is_ptr(type))
+ fprintf(file, " *)__frame->_StubMsg.Buffer = *");
+ else
+@@ -4059,7 +4090,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ else if (phase == PHASE_UNMARSHAL)
+ {
+ print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
+ print_file(file, indent, "{\n");
+ print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
+@@ -4071,12 +4102,12 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
+ fprintf(file, " = (");
+ else
+ fprintf(file, " = *(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
+ }
+
+ print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
+- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
++ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
+ fprintf(file, ");\n");
+ }
+ }
+@@ -4092,7 +4123,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
+ {
+ expr_t *x = NULL;
+
+- for ( ; is_array(t); t = type_array_get_element(t))
++ for ( ; is_array(t); t = type_array_get_element_type(t))
+ if (type_array_has_conformance(t) &&
+ type_array_get_conformance(t)->type != EXPR_VOID)
+ {
+@@ -4110,7 +4141,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 (;;)
+ {
+@@ -4162,7 +4193,7 @@ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local
+ break;
+ }
+ case TGT_POINTER:
+- type = type_pointer_get_ref(type);
++ type = type_pointer_get_ref_type(type);
+ continue;
+ case TGT_INVALID:
+ case TGT_USER_TYPE:
+@@ -4184,7 +4215,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))
+@@ -4237,19 +4268,20 @@ 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);
+ }
+ }
+ else if (phase == PHASE_UNMARSHAL)
+ {
+- if (pass == PASS_OUT)
++ if (pass == PASS_OUT || pass == PASS_RETURN)
+ {
+ if (!in_attr)
+ print_file(file, indent, "*%s%s = 0;\n", local_var_prefix, var->name);
+ print_file(file, indent, "NdrClientContextUnmarshall(\n");
+ print_file(file, indent + 1, "&__frame->_StubMsg,\n");
+- print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s,\n", local_var_prefix, var->name);
++ print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s%s,\n",
++ pass == PASS_RETURN ? "&" : "", local_var_prefix, var->name);
+ print_file(file, indent + 1, "__frame->_Handle);\n");
+ }
+ else
+@@ -4343,10 +4375,10 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ ((tc == FC_SMVARRAY || tc == FC_LGVARRAY) && in_attr) ||
+ (tc == FC_CARRAY && !in_attr))
+ {
+- if (type_array_is_decl_as_ptr(type) && type->details.array.ptr_tfsoff)
++ if (type_array_is_decl_as_ptr(type) && type_get_const_details(type)->array.ptr_tfsoff)
+ {
+ print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var,
+- type->details.array.ptr_tfsoff);
++ type_get_const_details(type)->array.ptr_tfsoff);
+ break;
+ }
+ print_phase_function(file, indent, array_type, local_var_prefix, phase, var, start_offset);
+@@ -4380,9 +4412,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_declspec_decl(file, &var->declspec, NULL);
+ fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
+- write_type_decl(file, var->type, NULL);
++ write_declspec_decl(file, &var->declspec, 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");
+@@ -4428,7 +4460,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
+ }
+ case TGT_POINTER:
+ {
+- const type_t *ref = type_pointer_get_ref(type);
++ const type_t *ref = type_pointer_get_ref_type(type);
+ if (pointer_type == FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
+ {
+ case TGT_BASIC:
+@@ -4549,14 +4581,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
+ write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var );
+ }
+ }
+@@ -4597,57 +4629,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))
+ {
+- print_file(file, indent, "%s", "");
+- write_type_decl(file, var->type, var->name);
+- fprintf(file, ";\n");
++ if (is_context_handle(var->declspec.type))
++ print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
++ else
++ {
++ print_file(file, indent, "%s", "");
++ write_declspec_decl(file, &var->declspec, var->name);
++ fprintf(file, ";\n");
++ }
+ }
+
+- if (!type_get_function_args(func->type))
++ if (!type_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ in_attr = is_attr(var->attrs, ATTR_IN);
+ out_attr = is_attr(var->attrs, ATTR_OUT);
+ 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;
++ const decl_spec_t *declspec_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))
++ declspec_to_print = &var->declspec;
+ else
+- type_to_print = type_pointer_get_ref(var->type);
++ declspec_to_print = type_pointer_get_ref(var->declspec.type);
+ sprintf(name, "_W%u", i++);
+- write_type_decl(file, type_to_print, name);
++ write_declspec_decl(file, declspec_to_print, name);
+ fprintf(file, ";\n");
+ }
+
+ print_file(file, indent, "%s", "");
+- write_type_decl_left(file, var->type);
++ write_declspec_decl_left(file, &var->declspec);
+ 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);
+ }
+ }
+@@ -4661,10 +4698,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
+ {
+ in_attr = is_attr(var->attrs, ATTR_IN);
+ out_attr = is_attr(var->attrs, ATTR_OUT);
+@@ -4675,7 +4712,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");
+@@ -4684,15 +4721,15 @@ 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))
++ type = type_array_get_element_type(type))
+ {
+ write_expr(file, type_array_get_conformance(type), TRUE,
+ TRUE, NULL, NULL, local_var_prefix);
+@@ -4702,9 +4739,9 @@ 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))
++ type = type_array_get_element_type(type))
+ {
+ write_expr(file, type_array_get_conformance(type), TRUE,
+ TRUE, NULL, NULL, local_var_prefix);
+@@ -4718,7 +4755,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_type(var->declspec.type);
+ switch (typegen_detect_type(ref, var->attrs, TDT_IGNORE_STRINGS))
+ {
+ case TGT_BASIC:
+@@ -4738,7 +4775,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
+ print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i);
+ break;
+ }
+- ref = type_array_get_element(ref);
++ ref = type_array_get_element_type(ref);
+ /* fall through */
+ case TGT_STRUCT:
+ case TGT_UNION:
+@@ -4771,14 +4808,14 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
+ const char *var_decl, int add_retval )
+ {
+ var_t *retval = type_function_get_retval( func );
+- const var_list_t *args = type_get_function_args( func );
++ const var_list_t *args = type_function_get_args( func );
+ const var_t *arg;
+ int needs_packing;
+ unsigned int align = 0;
+
+ 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);
+
+@@ -4790,26 +4827,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_declspec_left( file, &arg->declspec, 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_declspec_decl( file, &retval->declspec, 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 );
+@@ -4821,7 +4858,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_function_get_args( func->declspec.type );
+ const var_t *var;
+
+ if (!args) return;
+@@ -4854,10 +4891,11 @@ int write_expr_eval_routines(FILE *file, const char *iface)
+ }
+ else
+ {
++ decl_spec_t declspec;
+ print_file(file, 1, "%s", "");
+- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
++ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
+ fprintf(file, " *%s = (", var_name);
+- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
++ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
+ fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
+ }
+ print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
+@@ -4951,9 +4989,10 @@ 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 );
++ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
++ type_t *rettype = retdeclspec->type;
+ int has_ret = !is_void( rettype );
+- const var_list_t *args = type_get_function_args( func->type );
++ const var_list_t *args = type_function_get_args( func->declspec.type );
+ const var_t *arg;
+ int len, needs_params = 0;
+
+@@ -4964,7 +5003,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 )
+@@ -5001,7 +5040,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
+ if (has_ret)
+ {
+ print_file( file, 1, "return (" );
+- write_type_decl_left(file, rettype);
++ write_declspec_decl_left(file, retdeclspec);
+ fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" );
+ }
+ print_file( file, 0, "}\n\n");
+@@ -5029,7 +5068,7 @@ void write_exceptions( FILE *file )
+ fprintf( file, " EXCEPTION_REGISTRATION_RECORD frame; \\\n");
+ fprintf( file, " __filter_func filter; \\\n");
+ fprintf( file, " __finally_func finally; \\\n");
+- fprintf( file, " sigjmp_buf jmp; \\\n");
++ fprintf( file, " __wine_jmp_buf jmp; \\\n");
+ fprintf( file, " DWORD code; \\\n");
+ fprintf( file, " unsigned char abnormal_termination; \\\n");
+ fprintf( file, " unsigned char filter_level; \\\n");
+@@ -5049,13 +5088,13 @@ void write_exceptions( FILE *file )
+ fprintf( file, " __wine_pop_frame( &exc_frame->frame );\n");
+ fprintf( file, " }\n");
+ fprintf( file, " exc_frame->filter_level = 0;\n");
+- fprintf( file, " siglongjmp( exc_frame->jmp, 1 );\n");
++ fprintf( file, " __wine_longjmp( &exc_frame->jmp, 1 );\n");
+ fprintf( file, "}\n");
+ fprintf( file, "\n");
+- fprintf( file, "static DWORD __widl_exception_handler( EXCEPTION_RECORD *record,\n");
+- fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
+- fprintf( file, " CONTEXT *context,\n");
+- fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
++ fprintf( file, "static DWORD __cdecl __widl_exception_handler( EXCEPTION_RECORD *record,\n");
++ fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
++ fprintf( file, " CONTEXT *context,\n");
++ fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
+ fprintf( file, "{\n");
+ fprintf( file, " struct __exception_frame *exc_frame = (struct __exception_frame *)frame;\n");
+ fprintf( file, "\n");
+@@ -5075,7 +5114,7 @@ void write_exceptions( FILE *file )
+ fprintf( file, "}\n");
+ fprintf( file, "\n");
+ fprintf( file, "#define RpcTryExcept \\\n");
+- fprintf( file, " if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
++ fprintf( file, " if (!__wine_setjmpex( &__frame->jmp, &__frame->frame )) \\\n");
+ fprintf( file, " { \\\n");
+ fprintf( file, " if (!__frame->finally_level) \\\n" );
+ fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
+diff --git a/mingw-w64-tools/widl/src/typelib.c b/mingw-w64-tools/widl/src/typelib.c
+index 9b1de2c8..2c2b1276 100644
+--- a/mingw-w64-tools/widl/src/typelib.c
++++ b/mingw-w64-tools/widl/src/typelib.c
+@@ -97,9 +97,9 @@ static unsigned short builtin_vt(const type_t *t)
+ {
+ const type_t *elem_type;
+ if (is_array(t))
+- elem_type = type_array_get_element(t);
++ elem_type = type_array_get_element_type(t);
+ else
+- elem_type = type_pointer_get_ref(t);
++ elem_type = type_pointer_get_ref_type(t);
+ if (type_get_type(elem_type) == TYPE_BASIC)
+ {
+ switch (type_basic_get_type(elem_type))
+@@ -129,7 +129,8 @@ unsigned short get_type_vt(type_t *t)
+ if (vt) return vt;
+ }
+
+- if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC))
++ if (type_is_alias(t) &&
++ (is_attr(t->attrs, ATTR_PUBLIC) || is_attr(t->attrs, ATTR_WIREMARSHAL)))
+ return VT_USERDEFINED;
+
+ switch (type_get_type(t)) {
+@@ -169,7 +170,7 @@ unsigned short get_type_vt(type_t *t)
+ else
+ return VT_I8;
+ case TYPE_BASIC_INT3264:
+- if (typelib_kind == SYS_WIN64)
++ if (pointer_size == 8)
+ {
+ if (type_basic_get_sign(t) > 0)
+ return VT_UI8;
+@@ -198,7 +199,7 @@ unsigned short get_type_vt(type_t *t)
+ case TYPE_ARRAY:
+ if (type_array_is_decl_as_ptr(t))
+ {
+- if (match(type_array_get_element(t)->name, "SAFEARRAY"))
++ if (match(type_array_get_element_type(t)->name, "SAFEARRAY"))
+ return VT_SAFEARRAY;
+ return VT_PTR;
+ }
+diff --git a/mingw-w64-tools/widl/src/typetree.c b/mingw-w64-tools/widl/src/typetree.c
+index b93806be..f52b785f 100644
+--- a/mingw-w64-tools/widl/src/typetree.c
++++ b/mingw-w64-tools/widl/src/typetree.c
+@@ -30,12 +30,16 @@
+ #include "typetree.h"
+ #include "header.h"
+
+-type_t *duptype(type_t *t, int dupname)
++/* this function is only used in declare_var in parser.y, see FIXME note */
++type_t *dup_pointer_type(type_t *t)
+ {
+- type_t *d = alloc_type();
++ type_t *d;
+
++ assert(is_ptr(t) && t->details.pointer.def_fc != FC_RP);
++
++ d = alloc_type();
+ *d = *t;
+- if (dupname && t->name)
++ if (t->name)
+ d->name = xstrdup(t->name);
+
+ return d;
+@@ -49,7 +53,6 @@ type_t *make_type(enum type_type type)
+ t->type_type = type;
+ t->attrs = NULL;
+ t->c_name = NULL;
+- t->orig = NULL;
+ memset(&t->details, 0, sizeof(t->details));
+ t->typestring_offset = 0;
+ t->ptrdesc = 0;
+@@ -137,7 +140,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 +150,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)
+ {
+@@ -178,35 +181,29 @@ type_t *type_new_function(var_list_t *args)
+ return t;
+ }
+
+-type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
++type_t *type_new_pointer(unsigned char pointer_default, type_t *ref)
+ {
+ type_t *t = make_type(TYPE_POINTER);
+ t->details.pointer.def_fc = pointer_default;
+- t->details.pointer.ref = ref;
+- t->attrs = attrs;
++ t->details.pointer.ref.type = ref;
+ return t;
+ }
+
+-type_t *type_new_alias(type_t *t, const char *name)
++type_t *type_new_alias(const decl_spec_t *ds, const char *name)
+ {
+- type_t *a = duptype(t, 0);
+-
++ type_t *a = make_type(ds->type->type_type);
+ a->name = xstrdup(name);
+ a->attrs = NULL;
+- a->orig = t;
++ a->details.alias.aliasee = *ds;
+ a->is_alias = TRUE;
+- /* for pointer types */
+- a->details = t->details;
+- init_loc_info(&a->loc_info);
+-
+ return a;
+ }
+
+ type_t *type_new_module(char *name)
+ {
+ type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
+- if (type->type_type != TYPE_MODULE || type->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type->type_type != TYPE_MODULE || type_is_defined(type))
++ error_loc("BAZ %s: redefinition error; original definition was at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->name = name;
+ return type;
+@@ -215,15 +212,15 @@ type_t *type_new_module(char *name)
+ type_t *type_new_coclass(char *name)
+ {
+ type_t *type = get_type(TYPE_COCLASS, name, NULL, 0);
+- if (type->type_type != TYPE_COCLASS || type->defined)
+- error_loc("%s: redefinition error; original definition was at %s:%d\n",
++ if (type->type_type != TYPE_COCLASS || type_is_defined(type))
++ error_loc("BING %s: redefinition error; original definition was at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->name = name;
+ return type;
+ }
+
+
+-type_t *type_new_array(const char *name, type_t *element, int declptr,
++type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
+ unsigned int dim, expr_t *size_is, expr_t *length_is,
+ unsigned char ptr_default_fc)
+ {
+@@ -235,7 +232,9 @@ type_t *type_new_array(const char *name, type_t *element, int declptr,
+ t->details.array.size_is = size_is;
+ else
+ t->details.array.dim = dim;
+- t->details.array.elem = element;
++ if (element) {
++ t->details.array.elem = *element;
++ }
+ t->details.array.ptr_def_fc = ptr_default_fc;
+ return t;
+ }
+@@ -273,80 +272,99 @@ type_t *type_new_void(void)
+
+ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
+ {
+- type_t *tag_type = name ? find_type(name, namespace, tsENUM) : NULL;
+- type_t *t = make_type(TYPE_ENUM);
+- t->name = name;
+- t->namespace = namespace;
+-
+- if (tag_type && tag_type->details.enumeration)
+- t->details.enumeration = tag_type->details.enumeration;
+- else if (defined)
++ type_t *t = NULL;
++
++ if (name)
++ t = find_type(name, namespace, tsENUM);
++
++ if (!t)
+ {
+- t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
+- t->details.enumeration->enums = enums;
+- t->defined = TRUE;
++ t = make_type(TYPE_ENUM);
++ t->name = name;
++ t->namespace = namespace;
++ if (name)
++ reg_type(t, name, namespace, tsENUM);
+ }
+
+- if (name)
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, namespace, tsENUM);
++ {
++ t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
++ t->details.enumeration->enums = enums;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields)
+ {
+- type_t *tag_type = name ? find_type(name, namespace, tsSTRUCT) : NULL;
+- type_t *t;
+-
+- /* avoid creating duplicate typelib type entries */
+- if (tag_type && do_typelib) return tag_type;
++ type_t *t = NULL;
+
+- t = make_type(TYPE_STRUCT);
+- t->name = name;
+- t->namespace = namespace;
++ if (name)
++ t = find_type(name, namespace, tsSTRUCT);
+
+- if (tag_type && tag_type->details.structure)
+- t->details.structure = tag_type->details.structure;
+- else if (defined)
++ if (!t)
+ {
+- t->details.structure = xmalloc(sizeof(*t->details.structure));
+- t->details.structure->fields = fields;
+- t->defined = TRUE;
++ t = make_type(TYPE_STRUCT);
++ t->name = name;
++ t->namespace = namespace;
++ if (name)
++ reg_type(t, name, namespace, tsSTRUCT);
+ }
+- if (name)
++
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, namespace, tsSTRUCT);
++ {
++ t->details.structure = xmalloc(sizeof(*t->details.structure));
++ t->details.structure->fields = fields;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
+ {
+- type_t *tag_type = name ? find_type(name, NULL, tsUNION) : NULL;
+- type_t *t = make_type(TYPE_UNION);
+- t->name = name;
+- if (tag_type && tag_type->details.structure)
+- t->details.structure = tag_type->details.structure;
+- else if (defined)
++ type_t *t = NULL;
++
++ if (name)
++ t = find_type(name, NULL, tsUNION);
++
++ if (!t)
+ {
+- t->details.structure = xmalloc(sizeof(*t->details.structure));
+- t->details.structure->fields = fields;
+- t->defined = TRUE;
++ t = make_type(TYPE_UNION);
++ t->name = name;
++ if (name)
++ reg_type(t, name, NULL, tsUNION);
+ }
+- if (name)
++
++ if (!type_is_defined(t))
+ {
+ if (defined)
+- reg_type(t, name, NULL, tsUNION);
++ {
++ t->details.structure = xmalloc(sizeof(*t->details.structure));
++ t->details.structure->fields = fields;
++ t->defined = TRUE;
++ }
+ else
++ {
+ add_incomplete(t);
++ }
+ }
++
+ return t;
+ }
+
+@@ -354,7 +372,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 +448,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;
+@@ -438,6 +456,7 @@ static int compute_method_indexes(type_t *iface)
+
+ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = NULL;
+ iface->details.iface->disp_methods = NULL;
+@@ -451,6 +470,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
+
+ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = props;
+ iface->details.iface->disp_methods = methods;
+@@ -465,6 +485,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
+
+ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
+ {
++ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
+ dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
+ dispiface->details.iface->disp_props = NULL;
+ dispiface->details.iface->disp_methods = NULL;
+@@ -479,6 +500,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
+
+ void type_module_define(type_t *module, statement_list_t *stmts)
+ {
++ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
+ if (module->details.module) error_loc("multiple definition error\n");
+ module->details.module = xmalloc(sizeof(*module->details.module));
+ module->details.module->stmts = stmts;
+@@ -487,6 +509,7 @@ void type_module_define(type_t *module, statement_list_t *stmts)
+
+ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
+ {
++ assert(type_get_type_detect_alias(coclass) == TYPE_COCLASS);
+ coclass->details.coclass.ifaces = ifaces;
+ coclass->defined = TRUE;
+ return coclass;
+diff --git a/mingw-w64-tools/widl/src/typetree.h b/mingw-w64-tools/widl/src/typetree.h
+index fc134cd5..96fcae8d 100644
+--- a/mingw-w64-tools/widl/src/typetree.h
++++ b/mingw-w64-tools/widl/src/typetree.h
+@@ -30,10 +30,10 @@ enum name_type {
+ };
+
+ type_t *type_new_function(var_list_t *args);
+-type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
+-type_t *type_new_alias(type_t *t, const char *name);
++type_t *type_new_pointer(unsigned char pointer_default, type_t *ref);
++type_t *type_new_alias(const decl_spec_t *aliasee, const char *name);
+ type_t *type_new_module(char *name);
+-type_t *type_new_array(const char *name, type_t *element, int declptr,
++type_t *type_new_array(const char* name, const decl_spec_t *element, int declptr,
+ unsigned int dim, expr_t *size_is, expr_t *length_is,
+ unsigned char ptr_default_fc);
+ type_t *type_new_basic(enum type_basic_type basic_type);
+@@ -53,14 +53,38 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
+ int type_is_equal(const type_t *type1, const type_t *type2);
+ const char *type_get_name(const type_t *type, enum name_type name_type);
+
+-/* FIXME: shouldn't need to export this */
+-type_t *duptype(type_t *t, int dupname);
++/* copy pointer type to deal with need for duplicate typeformat strings */
++type_t *dup_pointer_type(type_t *t);
++
++#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
++ if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
++ if (stmt->type == STMT_DECLARATION && stmt->u.var->declspec.stgclass == STG_NONE && \
++ type_get_type_detect_alias(stmt->u.var->declspec.type) == TYPE_FUNCTION)
++
++static inline enum type_type type_get_type_detect_alias(const type_t *type)
++{
++ if (type->is_alias)
++ return TYPE_ALIAS;
++ return type->type_type;
++}
++
++static inline int statements_has_func(const statement_list_t *stmts)
++{
++ const statement_t *stmt;
++ int has_func = 0;
++ STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
++ {
++ has_func = 1;
++ break;
++ }
++ return has_func;
++}
+
+ /* un-alias the type until finding the non-alias type */
+ static inline type_t *type_get_real_type(const type_t *type)
+ {
+ if (type->is_alias)
+- return type_get_real_type(type->orig);
++ return type_get_real_type(type->details.alias.aliasee.type);
+ else
+ return (type_t *)type;
+ }
+@@ -105,9 +129,14 @@ static inline var_t *type_function_get_retval(const type_t *type)
+ return type->details.function->retval;
+ }
+
++static inline const decl_spec_t *type_function_get_retdeclspec(const type_t *type)
++{
++ return &type_function_get_retval(type)->declspec;
++}
++
+ static inline type_t *type_function_get_rettype(const type_t *type)
+ {
+- return type_function_get_retval(type)->type;
++ return type_function_get_retdeclspec(type)->type;
+ }
+
+ static inline var_list_t *type_enum_get_values(const type_t *type)
+@@ -142,7 +171,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;
+@@ -250,11 +279,16 @@ static inline expr_t *type_array_get_variance(const type_t *type)
+ return type->details.array.length_is;
+ }
+
+-static inline type_t *type_array_get_element(const type_t *type)
++static inline const decl_spec_t *type_array_get_element(const type_t *type)
+ {
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_ARRAY);
+- return type->details.array.elem;
++ return &type->details.array.elem;
++}
++
++static inline type_t *type_array_get_element_type(const type_t *type)
++{
++ return type_array_get_element(type)->type;
+ }
+
+ static inline int type_array_is_decl_as_ptr(const type_t *type)
+@@ -276,10 +310,15 @@ static inline int type_is_alias(const type_t *type)
+ return type->is_alias;
+ }
+
+-static inline type_t *type_alias_get_aliasee(const type_t *type)
++static inline const decl_spec_t *type_alias_get_aliasee(const type_t *type)
+ {
+ assert(type_is_alias(type));
+- return type->orig;
++ return &type->details.alias.aliasee;
++}
++
++static inline type_t *type_alias_get_aliasee_type(const type_t *type)
++{
++ return type_alias_get_aliasee(type)->type;
+ }
+
+ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
+@@ -289,11 +328,16 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
+ return type->details.coclass.ifaces;
+ }
+
+-static inline type_t *type_pointer_get_ref(const type_t *type)
++static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
+ {
+ type = type_get_real_type(type);
+ assert(type_get_type(type) == TYPE_POINTER);
+- return type->details.pointer.ref;
++ return &type->details.pointer.ref;
++}
++
++static inline type_t *type_pointer_get_ref_type(const type_t *type)
++{
++ return type_pointer_get_ref(type)->type;
+ }
+
+ static inline unsigned char type_pointer_get_default_fc(const type_t *type)
+@@ -317,4 +361,54 @@ static inline const expr_t *type_bitfield_get_bits(const type_t *type)
+ return type->details.bitfield.bits;
+ }
+
++/* gets pointer to details_t union with the assumption the caller wants to write to it
++ * so assert if we're actually dealing with an alias and writing to the details would
++ * overwrite the alias_details
++ */
++static inline details_t *type_get_details(type_t* type)
++{
++ assert(!type_is_alias(type));
++ return &type->details;
++}
++
++/* const overload of type_get_details */
++
++static inline const details_t *type_get_const_details(const type_t* type)
++{
++ assert(!type_is_alias(type));
++ return &type->details;
++}
++
++static inline int type_is_pointerish(const type_t *type)
++{
++ type = type_get_real_type(type);
++ return type_get_type(type) == TYPE_ARRAY || type_get_type(type) == TYPE_POINTER;
++}
++
++static inline type_t * type_get_pointer_chain_tail(const type_t *type)
++{
++ type_t *pointee = NULL;
++ type_t *pointer = type_get_real_type(type);
++
++ if (type_get_type(pointer) == TYPE_ARRAY)
++ {
++ pointee = type_array_get_element_type(pointer);
++ }
++ else if (type_get_type(pointer) == TYPE_POINTER)
++ {
++ pointee = type_pointer_get_ref_type(pointer);
++ }
++ else
++ {
++ assert(FALSE);
++ }
++
++ if (type_is_pointerish(pointee))
++ {
++ return type_get_pointer_chain_tail(pointee);
++ }
++
++ return pointee;
++}
++
+ #endif /* WIDL_TYPE_TREE_H */
+diff --git a/mingw-w64-tools/widl/src/widl.c b/mingw-w64-tools/widl/src/widl.c
+index 1af42509..8542e518 100644
+--- a/mingw-w64-tools/widl/src/widl.c
++++ b/mingw-w64-tools/widl/src/widl.c
+@@ -44,11 +44,6 @@
+ #include "header.h"
+ #include "pathtools.h"
+
+-/* future options to reserve characters for: */
+-/* A = ACF input filename */
+-/* J = do not search standard include path */
+-/* w = select win16/win32 output (?) */
+-
+ static const char usage[] =
+ "Usage: widl [options...] infile.idl\n"
+ " or: widl [options...] --dlldata-only name1 [name2...]\n"
+@@ -64,7 +59,7 @@ static const char usage[] =
+ " -H file Name of header file (default is infile.h)\n"
+ " -I path Set include search dir to path (multiple -I allowed)\n"
+ " --local-stubs=file Write empty stubs for call_as/local methods to file\n"
+-" -m32, -m64 Set the kind of typelib to build (Win32 or Win64)\n"
++" -m32, -m64 Set the target architecture (Win32 or Win64)\n"
+ " -N Do not preprocess input\n"
+ " --oldnames Use old naming conventions\n"
+ " -o, --output=NAME Set the output file name\n"
+@@ -82,8 +77,7 @@ static const char usage[] =
+ " -u Generate interface identifiers file\n"
+ " -V Print version and exit\n"
+ " -W Enable pedantic warnings\n"
+-" --win32 Only generate 32-bit code\n"
+-" --win64 Only generate 64-bit code\n"
++" --win32, --win64 Set the target architecture (Win32 or Win64)\n"
+ " --win32-align n Set win32 structure alignment to 'n'\n"
+ " --win64-align n Set win64 structure alignment to 'n'\n"
+ "Debug level 'n' is a bitmask with following meaning:\n"
+@@ -98,6 +92,20 @@ static const char usage[] =
+ static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
+ "Copyright 2002 Ove Kaaven\n";
+
++#ifdef __i386__
++enum target_cpu target_cpu = CPU_x86;
++#elif defined(__x86_64__)
++enum target_cpu target_cpu = CPU_x86_64;
++#elif defined(__powerpc__)
++enum target_cpu target_cpu = CPU_POWERPC;
++#elif defined(__arm__)
++enum target_cpu target_cpu = CPU_ARM;
++#elif defined(__aarch64__)
++enum target_cpu target_cpu = CPU_ARM64;
++#else
++#error Unsupported CPU
++#endif
++
+ int debuglevel = DEBUGLEVEL_NONE;
+ int parser_debug, yy_flex_debug;
+
+@@ -114,8 +122,6 @@ int do_idfile = 0;
+ int do_dlldata = 0;
+ static int no_preprocess = 0;
+ int old_names = 0;
+-int do_win32 = 1;
+-int do_win64 = 1;
+ int win32_packing = 8;
+ int win64_packing = 8;
+ int winrt_mode = 0;
+@@ -148,7 +154,6 @@ int line_number = 1;
+ static FILE *idfile;
+
+ unsigned int pointer_size = 0;
+-syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
+
+ time_t now;
+
+@@ -188,6 +193,7 @@ static const struct option long_options[] = {
+ { "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
+ { "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
+ { "robust", 0, NULL, ROBUST_OPTION },
++ { "target", 0, NULL, 'b' },
+ { "winrt", 0, NULL, RT_OPTION },
+ { "win32", 0, NULL, WIN32_OPTION },
+ { "win64", 0, NULL, WIN64_OPTION },
+@@ -269,20 +275,25 @@ static void set_target( const char *target )
+ {
+ static const struct
+ {
+- const char *name;
+- syskind_t kind;
++ const char *name;
++ enum target_cpu cpu;
+ } cpu_names[] =
+ {
+- { "i386", SYS_WIN32 },
+- { "i486", SYS_WIN32 },
+- { "i586", SYS_WIN32 },
+- { "i686", SYS_WIN32 },
+- { "i786", SYS_WIN32 },
+- { "amd64", SYS_WIN64 },
+- { "x86_64", SYS_WIN64 },
+- { "powerpc", SYS_WIN32 },
+- { "arm", SYS_WIN32 },
+- { "aarch64", SYS_WIN64 }
++ { "i386", CPU_x86 },
++ { "i486", CPU_x86 },
++ { "i586", CPU_x86 },
++ { "i686", CPU_x86 },
++ { "i786", CPU_x86 },
++ { "amd64", CPU_x86_64 },
++ { "x86_64", CPU_x86_64 },
++ { "powerpc", CPU_POWERPC },
++ { "arm", CPU_ARM },
++ { "armv5", CPU_ARM },
++ { "armv6", CPU_ARM },
++ { "armv7", CPU_ARM },
++ { "armv7a", CPU_ARM },
++ { "arm64", CPU_ARM64 },
++ { "aarch64", CPU_ARM64 },
+ };
+
+ unsigned int i;
+@@ -296,7 +307,7 @@ static void set_target( const char *target )
+ {
+ if (!strcmp( cpu_names[i].name, spec ))
+ {
+- typelib_kind = cpu_names[i].kind;
++ target_cpu = cpu_names[i].cpu;
+ free( spec );
+ return;
+ }
+@@ -484,6 +495,7 @@ static void write_id_data_stmts(const statement_list_t *stmts)
+ uuid = get_attrp(type->attrs, ATTR_UUID);
+ write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
+ type->name, uuid);
++ assert(type_get_type_detect_alias(type) == TYPE_INTERFACE);
+ if (type->details.iface->async_iface)
+ {
+ uuid = get_attrp(type->details.iface->async_iface->attrs, ATTR_UUID);
+@@ -606,12 +618,10 @@ int main(int argc,char *argv[])
+ use_abi_namespace = 1;
+ break;
+ case WIN32_OPTION:
+- do_win32 = 1;
+- do_win64 = 0;
++ pointer_size = 4;
+ break;
+ case WIN64_OPTION:
+- do_win32 = 0;
+- do_win64 = 1;
++ pointer_size = 8;
+ break;
+ case WIN32_ALIGN_OPTION:
+ win32_packing = strtol(optarg, NULL, 0);
+@@ -664,8 +674,8 @@ int main(int argc,char *argv[])
+ wpp_add_include_path(optarg);
+ break;
+ case 'm':
+- if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32;
+- else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64;
++ if (!strcmp( optarg, "32" )) pointer_size = 4;
++ else if (!strcmp( optarg, "64" )) pointer_size = 8;
+ break;
+ case 'N':
+ no_preprocess = 1;
+@@ -726,6 +736,7 @@ int main(int argc,char *argv[])
+ }
+
+ #ifdef DEFAULT_INCLUDE_DIR
++ wpp_add_include_path(DEFAULT_INCLUDE_DIR);
+ char exe_path[PATH_MAX];
+ get_executable_path (argv[0], &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0]));
+ char * rel_to_includedir = get_relative_path (DEFAULT_BINDIR, DEFAULT_INCLUDE_DIR);
+@@ -739,6 +750,26 @@ int main(int argc,char *argv[])
+ wpp_add_include_path(relocated_default_include_dir);
+ #endif
+
++ switch (target_cpu)
++ {
++ case CPU_x86:
++ if (pointer_size == 8) target_cpu = CPU_x86_64;
++ else pointer_size = 4;
++ break;
++ case CPU_x86_64:
++ if (pointer_size == 4) target_cpu = CPU_x86;
++ else pointer_size = 8;
++ break;
++ case CPU_ARM64:
++ if (pointer_size == 4) error( "Cannot build 32-bit code for this CPU\n" );
++ pointer_size = 8;
++ break;
++ default:
++ if (pointer_size == 8) error( "Cannot build 64-bit code for this CPU\n" );
++ pointer_size = 4;
++ break;
++ }
++
+ /* if nothing specified, try to guess output type from the output file name */
+ if (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
+ !do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata)
+diff --git a/mingw-w64-tools/widl/src/widl.h b/mingw-w64-tools/widl/src/widl.h
+index 118e2245..4f4252e3 100644
+--- a/mingw-w64-tools/widl/src/widl.h
++++ b/mingw-w64-tools/widl/src/widl.h
+@@ -45,8 +45,6 @@ extern int do_regscript;
+ extern int do_idfile;
+ extern int do_dlldata;
+ extern int old_names;
+-extern int do_win32;
+-extern int do_win64;
+ extern int win32_packing;
+ extern int win64_packing;
+ extern int winrt_mode;
+@@ -76,6 +74,13 @@ extern time_t now;
+ extern int line_number;
+ extern int char_number;
+
++enum target_cpu
++{
++ CPU_x86, CPU_x86_64, CPU_POWERPC, CPU_ARM, CPU_ARM64, CPU_LAST = CPU_ARM64
++};
++
++extern enum target_cpu target_cpu;
++
+ enum stub_mode
+ {
+ MODE_Os, /* inline stubs */
+diff --git a/mingw-w64-tools/widl/src/widltypes.h b/mingw-w64-tools/widl/src/widltypes.h
+index 08584de5..b9c5a07d 100644
+--- a/mingw-w64-tools/widl/src/widltypes.h
++++ b/mingw-w64-tools/widl/src/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;
+@@ -80,7 +81,6 @@ enum attr_type
+ ATTR_CASE,
+ ATTR_CODE,
+ ATTR_COMMSTATUS,
+- ATTR_CONST, /* const pseudo-attribute */
+ ATTR_CONTEXTHANDLE,
+ ATTR_CONTROL,
+ ATTR_DECODE,
+@@ -115,7 +115,6 @@ enum attr_type
+ ATTR_IMMEDIATEBIND,
+ ATTR_IMPLICIT_HANDLE,
+ ATTR_IN,
+- ATTR_INLINE,
+ ATTR_INPUTSYNC,
+ ATTR_LENGTHIS,
+ ATTR_LIBLCID,
+@@ -234,6 +233,18 @@ enum storage_class
+ STG_REGISTER,
+ };
+
++enum type_qualifier
++{
++ TYPE_QUALIFIER_NONE = 0,
++ TYPE_QUALIFIER_CONST = 1,
++};
++
++enum function_specifier
++{
++ FUNCTION_SPECIFIER_NONE,
++ FUNCTION_SPECIFIER_INLINE,
++};
++
+ enum statement_type
+ {
+ STMT_LIBRARY,
+@@ -293,6 +304,14 @@ struct str_list_entry_t
+ struct list entry;
+ };
+
++struct _decl_spec_t
++{
++ type_t *type;
++ enum storage_class stgclass;
++ enum type_qualifier typequalifier;
++ enum function_specifier funcspecifier;
++};
++
+ struct _attr_t {
+ enum attr_type type;
+ union {
+@@ -356,7 +375,7 @@ struct array_details
+ {
+ expr_t *size_is;
+ expr_t *length_is;
+- struct _type_t *elem;
++ struct _decl_spec_t elem;
+ unsigned int dim;
+ unsigned char ptr_def_fc;
+ unsigned char declptr; /* if declared as a pointer */
+@@ -376,7 +395,7 @@ struct basic_details
+
+ struct pointer_details
+ {
+- struct _type_t *ref;
++ struct _decl_spec_t ref;
+ unsigned char def_fc;
+ };
+
+@@ -386,6 +405,11 @@ struct bitfield_details
+ const expr_t *bits;
+ };
+
++struct alias_details
++{
++ struct _decl_spec_t aliasee;
++};
++
+ #define HASHMAX 64
+
+ struct namespace {
+@@ -414,26 +438,28 @@ enum type_type
+ TYPE_BITFIELD,
+ };
+
++typedef union _details_t
++{
++ struct struct_details *structure;
++ struct enumeration_details *enumeration;
++ struct func_details *function;
++ struct iface_details *iface;
++ struct module_details *module;
++ struct array_details array;
++ struct coclass_details coclass;
++ struct basic_details basic;
++ struct pointer_details pointer;
++ struct bitfield_details bitfield;
++ struct alias_details alias;
++} details_t;
++
+ struct _type_t {
+ const char *name;
+ struct namespace *namespace;
+ enum type_type type_type;
+ attr_list_t *attrs;
+- union
+- {
+- struct struct_details *structure;
+- struct enumeration_details *enumeration;
+- struct func_details *function;
+- struct iface_details *iface;
+- struct module_details *module;
+- struct array_details array;
+- struct coclass_details coclass;
+- struct basic_details basic;
+- struct pointer_details pointer;
+- struct bitfield_details bitfield;
+- } details;
++ details_t details;
+ const char *c_name;
+- type_t *orig; /* dup'd types */
+ unsigned int typestring_offset;
+ unsigned int ptrdesc; /* used for complex structs */
+ int typelib_idx;
+@@ -449,14 +475,20 @@ 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;
+
+ struct _loc_info_t loc_info;
++ /* this flag indicates that this var's type (or pointed to type in the case of
++ * array or pointer) was not fully defined at the time of declaration.
++ * If this flag is set to TRUE then the type definition will not be written for this var
++ * If this flag is set to FALSE then the type definition will only be written if it has not
++ * been written yet (determined by the type_t's 'written' flag)
++ */
++ int declonly : 1;
+
+ /* parser-internal */
+ struct list entry;
+@@ -464,7 +496,7 @@ struct _var_t {
+
+ struct _declarator_t {
+ var_t *var;
+- type_t *type;
++ decl_spec_t declspec;
+ type_t *func_type;
+ expr_t *bits;
+
+@@ -497,6 +529,7 @@ struct _importinfo_t {
+ };
+
+ struct _importlib_t {
++ int offset;
+ char *name;
+
+ int version;
+@@ -539,6 +572,13 @@ struct _statement_t {
+ typelib_t *lib;
+ type_list_t *type_list;
+ } u;
++ /* this flag indicates that this statement's type (or pointed to type in the case of
++ * array or pointer) was not fully defined at the time of declaration.
++ * If this flag is set to TRUE then the type definition will not be written for this statement
++ * If this flag is set to FALSE then the type definition will only be written if it has not
++ * been written yet (determined by the type_t's 'written' flag)
++ */
++ int declonly : 1;
+ };
+
+ struct _warning_t {
+@@ -553,11 +593,10 @@ typedef enum {
+ SYS_WIN64
+ } syskind_t;
+
+-extern syskind_t typelib_kind;
+ extern user_type_list_t user_type_list;
+ extern context_handle_list_t context_handle_list;
+ extern generic_handle_list_t generic_handle_list;
+-void check_for_additional_prototype_types(const var_list_t *list);
++void check_for_additional_prototype_types(type_t *type);
+
+ void init_types(void);
+ type_t *alloc_type(void);
+@@ -568,6 +607,12 @@ void clear_all_offsets(void);
+ #define tsSTRUCT 2
+ #define tsUNION 3
+
++static inline const char* ts_to_str(int t)
++{
++ static const char* strings[] = {"tsNULL", "tsENUM", "tsSTRUCT", "tsUNION"};
++ return strings[t];
++}
++
+ var_t *find_const(const char *name, int f);
+ type_t *find_type(const char *name, struct namespace *namespace, int t);
+ type_t *make_type(enum type_type type);
+@@ -582,38 +627,18 @@ void init_loc_info(loc_info_t *);
+
+ char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
+
+-static inline var_list_t *type_get_function_args(const type_t *func_type)
+-{
+- return func_type->details.function->args;
+-}
+-
+-static inline enum type_type type_get_type_detect_alias(const type_t *type)
+-{
+- if (type->is_alias)
+- return TYPE_ALIAS;
+- return type->type_type;
+-}
+-
+-#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
+- if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
+- if (stmt->type == STMT_DECLARATION && stmt->u.var->stgclass == STG_NONE && \
+- type_get_type_detect_alias(stmt->u.var->type) == TYPE_FUNCTION)
+-
+-static inline int statements_has_func(const statement_list_t *stmts)
++static inline int is_global_namespace(const struct namespace *namespace)
+ {
+- const statement_t *stmt;
+- int has_func = 0;
+- STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
+- {
+- has_func = 1;
+- break;
+- }
+- return has_func;
++ return !namespace->name;
+ }
+
+-static inline int is_global_namespace(const struct namespace *namespace)
++static inline decl_spec_t *init_declspec(decl_spec_t *declspec, type_t *type)
+ {
+- return !namespace->name;
++ declspec->type = type;
++ declspec->stgclass = STG_NONE;
++ declspec->typequalifier=TYPE_QUALIFIER_NONE;
++ declspec->funcspecifier=FUNCTION_SPECIFIER_NONE;
++ return declspec;
+ }
+
+ #endif
+diff --git a/mingw-w64-tools/widl/src/write_msft.c b/mingw-w64-tools/widl/src/write_msft.c
+index 88a80d12..da7ce89d 100644
+--- a/mingw-w64-tools/widl/src/write_msft.c
++++ b/mingw-w64-tools/widl/src/write_msft.c
+@@ -702,15 +702,15 @@ static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo)
+
+ guid_idx = ctl2_alloc_guid(typelib, &guid);
+
+- alloc_importfile(typelib, guid_idx, importlib->version&0xffff,
+- importlib->version>>16, importlib->name);
++ importlib->offset = alloc_importfile(typelib, guid_idx, importlib->version & 0xffff,
++ importlib->version >> 16, importlib->name);
+ }
+
+ if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) {
+ MSFT_ImpInfo impinfo;
+
+ impinfo.flags = importinfo->flags;
+- impinfo.oImpFile = 0;
++ impinfo.oImpFile = importlib->offset;
+
+ if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
+ MSFT_GuidEntry guid;
+@@ -763,7 +763,7 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
+ static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion);
+ static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls);
+ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface);
+-
++static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef);
+
+ /****************************************************************************
+ * encode_type
+@@ -862,8 +862,8 @@ static int encode_type(
+ case VT_PTR:
+ {
+ int next_vt;
+- for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref(type)) {
+- next_vt = get_type_vt(type_pointer_get_ref(type));
++ for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref_type(type)) {
++ next_vt = get_type_vt(type_pointer_get_ref_type(type));
+ if (next_vt != 0)
+ break;
+ }
+@@ -871,7 +871,7 @@ static int encode_type(
+ if (next_vt == 0)
+ next_vt = VT_VOID;
+
+- encode_type(typelib, next_vt, type_pointer_get_ref(type),
++ encode_type(typelib, next_vt, type_pointer_get_ref_type(type),
+ &target_type, &child_size);
+ /* these types already have an implicit pointer, so we don't need to
+ * add another */
+@@ -912,10 +912,10 @@ static int encode_type(
+
+ case VT_SAFEARRAY:
+ {
+- type_t *element_type = type_alias_get_aliasee(type_array_get_element(type));
++ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(type));
+ int next_vt = get_type_vt(element_type);
+
+- encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)),
++ encode_type(typelib, next_vt, type_alias_get_aliasee_type(type_array_get_element_type(type)),
+ &target_type, &child_size);
+
+ for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
+@@ -966,33 +966,61 @@ static int encode_type(
+ }
+ else
+ {
+- /* typedef'd types without public attribute aren't included in the typelib */
+- while (type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
+- type = type_alias_get_aliasee(type);
++ /* typedef'd types without public attribute aren't included in the typelib
++ * typedef'd types with a wire_marshal attribute must be included
++ */
++ while (type_is_alias(type))
++ {
++ if (is_attr(type->attrs, ATTR_WIREMARSHAL))
++ {
++ type = get_attrp(type->attrs, ATTR_WIREMARSHAL);
++ break;
++ }
++ else if(!is_attr(type->attrs, ATTR_PUBLIC))
++ {
++ type = type_alias_get_aliasee_type(type);
++ }
++ else
++ {
++ break;
++ }
++ }
+
+ chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
+ type->name, type_get_type(type));
+
+- switch (type_get_type(type))
++ /* we've either fully resolved the typedef down to an actual type or
++ * we must include the typedef because it's a wiremarshal (or public) type
++ */
++ if (type_is_alias(type))
+ {
+- case TYPE_STRUCT:
+- add_structure_typeinfo(typelib, type);
+- break;
+- case TYPE_INTERFACE:
+- add_interface_typeinfo(typelib, type);
+- break;
+- case TYPE_ENUM:
+- add_enum_typeinfo(typelib, type);
+- break;
+- case TYPE_UNION:
+- add_union_typeinfo(typelib, type);
+- break;
+- case TYPE_COCLASS:
+- add_coclass_typeinfo(typelib, type);
+- break;
+- default:
+- error("encode_type: VT_USERDEFINED - unhandled type %d\n",
+- type_get_type(type));
++ add_typedef_typeinfo(typelib, type);
++ }
++ else
++ {
++ switch (type_get_type(type))
++ {
++ case TYPE_STRUCT:
++ add_structure_typeinfo(typelib, type);
++ break;
++ case TYPE_INTERFACE:
++ add_interface_typeinfo(typelib, type);
++ break;
++ case TYPE_ENUM:
++ add_enum_typeinfo(typelib, type);
++ break;
++ /* fallthrough */
++ case TYPE_UNION:
++ case TYPE_ENCAPSULATED_UNION:
++ add_union_typeinfo(typelib, type);
++ break;
++ case TYPE_COCLASS:
++ add_coclass_typeinfo(typelib, type);
++ break;
++ default:
++ error("encode_type: VT_USERDEFINED - unhandled type %d\n",
++ type_get_type(type));
++ }
+ }
+
+ typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
+@@ -1056,7 +1084,7 @@ static int encode_var(
+ num_dims = 0;
+ for (atype = type;
+ is_array(atype) && !type_array_is_decl_as_ptr(atype);
+- atype = type_array_get_element(atype))
++ atype = type_array_get_element_type(atype))
+ ++num_dims;
+
+ chat("array with %d dimensions\n", num_dims);
+@@ -1071,7 +1099,7 @@ static int encode_var(
+ arraydata += 2;
+ for (atype = type;
+ is_array(atype) && !type_array_is_decl_as_ptr(atype);
+- atype = type_array_get_element(atype))
++ atype = type_array_get_element_type(atype))
+ {
+ arraydata[0] = type_array_get_dim(atype);
+ arraydata[1] = 0;
+@@ -1093,7 +1121,7 @@ static int encode_var(
+ vt = get_type_vt(type);
+ if (vt == VT_PTR) {
+ type_t *ref = is_ptr(type) ?
+- type_pointer_get_ref(type) : type_array_get_element(type);
++ type_pointer_get_ref_type(type) : type_array_get_element_type(type);
+ int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
+
+ if(skip_ptr == 2) {
+@@ -1114,7 +1142,7 @@ static int encode_var(
+ if (target_type & 0x80000000) {
+ mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
+ } else if (get_type_vt(ref) == VT_SAFEARRAY) {
+- type_t *element_type = type_alias_get_aliasee(type_array_get_element(ref));
++ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(ref));
+ mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
+ } else {
+ typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
+@@ -1204,7 +1232,7 @@ static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *e
+ if (type_get_type(type) == TYPE_ENUM) {
+ vt = VT_I4;
+ } else if (is_ptr(type)) {
+- vt = get_type_vt(type_pointer_get_ref(type));
++ vt = get_type_vt(type_pointer_get_ref_type(type));
+ if (vt == VT_USERDEFINED)
+ vt = VT_I4;
+ if (expr->cval)
+@@ -1301,8 +1329,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_function_get_args(func->declspec.type))
++ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
+ {
+ num_params++;
+ if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
+@@ -1444,7 +1472,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 +1499,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_function_get_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_function_get_args(func->declspec.type), var_t, entry )
+ {
+ int paramflags = 0;
+ int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
+@@ -1482,13 +1510,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 +1600,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_function_get_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_function_get_args(func->declspec.type), var_t, entry )
+ {
+ /* don't give the last arg of a [propput*] func a name */
+ if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */))
+@@ -1697,8 +1725,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;
+@@ -1977,6 +2005,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
+ var_t *var;
+ msft_typeinfo_t *msft_typeinfo;
+
++ assert(type_get_type_detect_alias(dispinterface) == TYPE_INTERFACE);
+ if (-1 < dispinterface->typelib_idx)
+ return;
+
+@@ -2181,7 +2210,7 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
+ if (-1 < tdef->typelib_idx)
+ return;
+
+- type = type_alias_get_aliasee(tdef);
++ type = type_alias_get_aliasee_type(tdef);
+
+ if (!type->name || strcmp(tdef->name, type->name) != 0)
+ {
+@@ -2297,6 +2326,7 @@ static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
+ const statement_t *stmt;
+ msft_typeinfo_t *msft_typeinfo;
+
++ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
+ if (-1 < module->typelib_idx)
+ return;
+
+@@ -2364,7 +2394,7 @@ static void add_entry(msft_typelib_t *typelib, const statement_t *stmt)
+ if (is_attr(type_entry->type->attrs, ATTR_PUBLIC))
+ add_typedef_typeinfo(typelib, type_entry->type);
+ else
+- add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type));
++ add_type_typeinfo(typelib, type_alias_get_aliasee_type(type_entry->type));
+ }
+ break;
+ }
+@@ -2653,8 +2683,6 @@ int create_msft_typelib(typelib_t *typelib)
+ GUID midl_info_guid = {0xde77ba65,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
+ char info_string[128];
+
+- pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
+-
+ msft = xmalloc(sizeof(*msft));
+ memset(msft, 0, sizeof(*msft));
+ msft->typelib = typelib;
+@@ -2662,7 +2690,7 @@ int create_msft_typelib(typelib_t *typelib)
+ ctl2_init_header(msft);
+ ctl2_init_segdir(msft);
+
+- msft->typelib_header.varflags |= typelib_kind;
++ msft->typelib_header.varflags |= (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
+
+ /*
+ * The following two calls return an offset or -1 if out of memory. We
diff --git a/projects/mingw-w64/build b/projects/mingw-w64/build
index 4be660d..faa5997 100644
--- a/projects/mingw-w64/build
+++ b/projects/mingw-w64/build
@@ -52,6 +52,9 @@ cd /var/tmp/build/builddir/mingw-w64/mingw-w64-pthread
make -j[% c("buildconf/num_procs") %]
make install
+# patch mingw with widl fixes for #27503 ( https://trac.torproject.org/projects/tor/ticket/27503 )
+patch -p1 -d /var/tmp/build/[% project %]-[% c("version") %] < $rootdir/27503.patch
+
mkdir -p /var/tmp/build/builddir/mingw-w64/widl32
cd /var/tmp/build/builddir/mingw-w64/widl32
/var/tmp/build/[% project %]-[% c("version") %]/mingw-w64-tools/widl/configure \
diff --git a/projects/mingw-w64/config b/projects/mingw-w64/config
index d0268cb..a2f0701 100644
--- a/projects/mingw-w64/config
+++ b/projects/mingw-w64/config
@@ -35,3 +35,4 @@ input_files:
- name: binutils
project: binutils
- filename: libtool-sort.patch
+ - filename: 27503.patch
1
0

[tor-browser-build/master] Bug 29430: Use obfs4proxy's meek_lite with utls instead of meek.
by gkï¼ torproject.org 28 Aug '19
by gkï¼ torproject.org 28 Aug '19
28 Aug '19
commit f022ea694df867a6bd06c44cb50c78d674bea9ed
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Fri Aug 23 09:50:26 2019 -0400
Bug 29430: Use obfs4proxy's meek_lite with utls instead of meek.
---
projects/goutls/config | 2 ++
projects/goutls/sessionid.patch | 25 +++++++++++++
projects/meek/build | 42 ----------------------
projects/meek/config | 17 ---------
projects/obfs4/build | 6 ++--
projects/obfs4/config | 2 +-
.../Docs/Licenses/PluggableTransports/LICENSE | 9 -----
.../Bundle-Data/PTConfigs/bridge_prefs.js | 2 +-
.../PTConfigs/linux/torrc-defaults-appendix | 5 +--
.../mac/TorBrowser.app.meek-http-helper/README | 13 -------
.../PTConfigs/mac/torrc-defaults-appendix | 5 +--
.../Bundle-Data/PTConfigs/meek-http-helper-user.js | 38 --------------------
.../PTConfigs/windows/torrc-defaults-appendix | 5 +--
projects/tor-browser/build | 23 ------------
projects/tor-browser/config | 3 --
15 files changed, 35 insertions(+), 162 deletions(-)
diff --git a/projects/goutls/config b/projects/goutls/config
index 0a1e416..d738305 100644
--- a/projects/goutls/config
+++ b/projects/goutls/config
@@ -27,3 +27,5 @@ input_files:
project: gocompress
- name: gobsaes
project: gobsaes
+ - filename: sessionid.patch
+ enable: '[% c("var/nightly") || c("var/alpha") %]'
diff --git a/projects/goutls/sessionid.patch b/projects/goutls/sessionid.patch
new file mode 100644
index 0000000..fd3636d
--- /dev/null
+++ b/projects/goutls/sessionid.patch
@@ -0,0 +1,25 @@
+From 4da67951864128358459681399dd208c49d5d001 Mon Sep 17 00:00:00 2001
+From: Rod Hynes <rod-hynes(a)users.noreply.github.com>
+Date: Mon, 12 Aug 2019 17:06:06 -0400
+Subject: [PATCH] Fix all-zeroes SessionID (#31)
+
+---
+ u_conn.go | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/u_conn.go b/u_conn.go
+index 9079460..2706373 100644
+--- a/u_conn.go
++++ b/u_conn.go
+@@ -121,7 +121,7 @@ func (uconn *UConn) SetSessionState(session *ClientSessionState) error {
+ }
+ }
+ var sessionID [32]byte
+- _, err := io.ReadFull(uconn.config.rand(), uconn.HandshakeState.Hello.SessionId)
++ _, err := io.ReadFull(uconn.config.rand(), sessionID[:])
+ if err != nil {
+ return err
+ }
+--
+2.22.0
+
diff --git a/projects/meek/build b/projects/meek/build
deleted file mode 100644
index 57185b3..0000000
--- a/projects/meek/build
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-[% c("var/set_default_env") -%]
-[% pc('go', 'var/setup', { go_tarfile => c('input_files_by_name/go') }) %]
-distdir=/var/tmp/dist/[% project %]
-[% c("var/set_PTDIR_DOCSDIR") -%]
-mkdir -p $PTDIR $DOCSDIR
-
-tar -C /var/tmp/dist -xf [% c('input_files_by_name/goptlib') %]
-
-mkdir -p /var/tmp/build
-tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
-cd /var/tmp/build/[% project %]-[% c('version') %]
-
-cd meek-client
-go build -ldflags '-s'
-cp -a meek-client[% IF c("var/windows") %].exe[% END %] $PTDIR
-
-cd ../meek-client-torbrowser
-go build -ldflags '-s'
-cp -a meek-client-torbrowser[% IF c("var/windows") %].exe[% END %] $PTDIR
-
-
-[% IF c("var/windows") %]
- cd ../terminateprocess-buffer
- go build -ldflags '-s'
- cp -a terminateprocess-buffer.exe $PTDIR
-[% END %]
-
-cd ..
-cp -a README doc/*.1[% IF c("var/windows") %].txt[% END %] $DOCSDIR
-
-cd firefox
-[% c('zip', {
- zip_src => [ '.' ],
- zip_args => '$distdir/meek-http-helper(a)bamsoftware.com.xpi',
- }) %]
-
-cd $distdir
-[% c('tar', {
- tar_src => [ '.' ],
- tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
- }) %]
diff --git a/projects/meek/config b/projects/meek/config
deleted file mode 100644
index 7d0fd2d..0000000
--- a/projects/meek/config
+++ /dev/null
@@ -1,17 +0,0 @@
-# vim: filetype=yaml sw=2
-version: 0.31
-git_url: https://git.torproject.org/pluggable-transports/meek.git
-git_hash: '[% c("version") %]'
-tag_gpg_id: 1
-gpg_keyring: meek.gpg
-filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %].tar.gz'
-var:
- container:
- use_container: 1
-
-input_files:
- - project: container-image
- - name: go
- project: go
- - name: goptlib
- project: goptlib
diff --git a/projects/obfs4/build b/projects/obfs4/build
index dedd1ef..3f650c4 100644
--- a/projects/obfs4/build
+++ b/projects/obfs4/build
@@ -11,7 +11,7 @@ tar -C /var/tmp/dist -xf [% c('input_files_by_name/siphash') %]
tar -C /var/tmp/dist -xf [% c('input_files_by_name/uniuri') %]
tar -C /var/tmp/dist -xf [% c('input_files_by_name/goxcrypto') %]
tar -C /var/tmp/dist -xf [% c('input_files_by_name/goxnet') %]
-[% IF c("var/nightly") -%]
+[% IF c("var/nightly") || c("var/alpha") -%]
tar -C /var/tmp/dist -xf [% c('input_files_by_name/goutls') %]
tar -C /var/tmp/dist -xf [% c('input_files_by_name/goxtext') %]
[% END -%]
@@ -20,14 +20,14 @@ mkdir -p /var/tmp/build
tar -C /var/tmp/build -xf [% project %]-[% c('version') %].tar.gz
cd /var/tmp/build/[% project %]-[% c('version') %]
-[% IF c("var/nightly") -%]
+[% IF c("var/nightly") || c("var/alpha") -%]
# Remove go.mod and go.sum files until we can build using Go module
# versioning (see bug 28325).
rm -f go.mod go.sum
[% END -%]
# Commit 70d0e90c861be34ce3c5425ef1366a0b2ceb3026 changed the canonical obfs4
# upstream repo to gitlab.com/yawning/obfs4.git.
-[% IF c("var/nightly") %]
+[% IF c("var/nightly") || c("var/alpha") %]
mkdir -p "$GOPATH/src/gitlab.com/yawning"
ln -sf "$PWD" "$GOPATH/src/gitlab.com/yawning/obfs4.git"
[% ELSE %]
diff --git a/projects/obfs4/config b/projects/obfs4/config
index 32d3435..48afc2f 100644
--- a/projects/obfs4/config
+++ b/projects/obfs4/config
@@ -1,5 +1,5 @@
# vim: filetype=yaml sw=2
-version: 0.0.7
+version: 0.0.11
git_url: https://git.torproject.org/pluggable-transports/obfs4.git
git_hash: 'obfs4proxy-[% c("version") %]'
tag_gpg_id: 1
diff --git a/projects/tor-browser/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE b/projects/tor-browser/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE
index 8bf0661..25d930e 100644
--- a/projects/tor-browser/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE
+++ b/projects/tor-browser/Bundle-Data/Docs/Licenses/PluggableTransports/LICENSE
@@ -154,15 +154,6 @@ warranty. See LICENSE.CC0.
===============================================================================
-meek
-
-To the extent possible under law, the authors have dedicated all
-copyright and related and neighboring rights to this software to the
-public domain worldwide. This software is distributed without any
-warranty. See LICENSE.CC0.
-
-===============================================================================
-
obfs4
Copyright (c) 2014, Yawning Angel <yawning at torproject dot org>
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
index 4eb4644..566de2e 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
@@ -14,6 +14,6 @@ pref("extensions.torlauncher.default_bridge.obfs4.9", "obfs4 85.31.186.26:443 91
pref("extensions.torlauncher.default_bridge.obfs4.10", "obfs4 216.252.162.21:46089 0DB8799466902192B6C7576D58D4F7F714EC87C1 cert=XPUwcQPxEXExHfJYX58gZXN7mYpos7VNAHbkgERNFg+FCVNzuYo1Wp+uMscl3aR9hO2DRQ iat-mode=0");
pref("extensions.torlauncher.default_bridge.obfs4.11", "obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0");
-pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
+pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek_lite 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
pref("extensions.torlauncher.default_bridge.snowflake.1", "snowflake 0.0.3.0:1 2B280B23E1107BB62ABFC40DDCC8824814F80A72");
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix b/projects/tor-browser/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix
index 75d5c5e..ac89698 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/linux/torrc-defaults-appendix
@@ -1,8 +1,5 @@
## obfs4proxy configuration
-ClientTransportPlugin obfs2,obfs3,obfs4,scramblesuit exec ./TorBrowser/Tor/PluggableTransports/obfs4proxy
-
-## meek configuration
-ClientTransportPlugin meek exec ./TorBrowser/Tor/PluggableTransports/meek-client-torbrowser -- ./TorBrowser/Tor/PluggableTransports/meek-client
+ClientTransportPlugin meek_lite,obfs2,obfs3,obfs4,scramblesuit exec ./TorBrowser/Tor/PluggableTransports/obfs4proxy
## snowflake configuration
ClientTransportPlugin snowflake exec ./TorBrowser/Tor/PluggableTransports/snowflake-client -url https://snowflake-broker.azureedge.net/ -front ajax.aspnetcdn.com -ice stun:stun.l.google.com:19302
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/mac/TorBrowser.app.meek-http-helper/README b/projects/tor-browser/Bundle-Data/PTConfigs/mac/TorBrowser.app.meek-http-helper/README
deleted file mode 100644
index f158eec..0000000
--- a/projects/tor-browser/Bundle-Data/PTConfigs/mac/TorBrowser.app.meek-http-helper/README
+++ /dev/null
@@ -1,13 +0,0 @@
-This directory contains a special headless configuration of the Tor
-Browser app, intended for use by meek-client-torbrowser and the
-meek-http-helper extension. It should not be run directly.
-
-All files in the Contents directory, other than Info.plist, are simply
-symlinked to their counterparts in ../../../../../Contents. Info.plist
-contains an additional configuration directive that prevents the
-headless browser from opening a useless second dock icon:
- <key>LSBackgroundOnly</key><true/>
-
-For background on this matter, see the ticket:
- meek-http-helper opens up a second dock icon
- https://trac.torproject.org/projects/tor/ticket/11429
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix b/projects/tor-browser/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix
index cf7cc2a..154bda4 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/mac/torrc-defaults-appendix
@@ -1,8 +1,5 @@
## obfs4proxy configuration
-ClientTransportPlugin obfs2,obfs3,obfs4,scramblesuit exec PluggableTransports/obfs4proxy
-
-## meek configuration
-ClientTransportPlugin meek exec PluggableTransports/meek-client-torbrowser -- PluggableTransports/meek-client
+ClientTransportPlugin meek_lite,obfs2,obfs3,obfs4,scramblesuit exec PluggableTransports/obfs4proxy
## snowflake configuration
ClientTransportPlugin snowflake exec PluggableTransports/snowflake-client -url https://snowflake-broker.azureedge.net/ -front ajax.aspnetcdn.com -ice stun:stun.l.google.com:19302
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/meek-http-helper-user.js b/projects/tor-browser/Bundle-Data/PTConfigs/meek-http-helper-user.js
deleted file mode 100644
index c62b066..0000000
--- a/projects/tor-browser/Bundle-Data/PTConfigs/meek-http-helper-user.js
+++ /dev/null
@@ -1,38 +0,0 @@
-// http://kb.mozillazine.org/User.js_file
-
-// The meek-http-helper extension uses dump to write its listening port number
-// to stdout.
-user_pref("browser.dom.window.dump.enabled", true);
-
-// Enable TLS session tickets (disabled by default in Tor Browser). Otherwise
-// there is a missing TLS extension.
-// https://trac.torproject.org/projects/tor/ticket/13442#comment:1
-user_pref("security.ssl.disable_session_identifiers", false);
-
-// Disable safe mode. In case of a crash, we don't want to prompt for a
-// safe-mode browser that has extensions disabled.
-// https://support.mozilla.org/en-US/questions/951221#answer-410562
-user_pref("toolkit.startup.max_resumed_crashes", -1);
-
-// Don't raise software update windows in this browser instance.
-// https://trac.torproject.org/projects/tor/ticket/14203
-user_pref("app.update.enabled", false);
-
-// Set a failsafe blackhole proxy of 127.0.0.1:9, to prevent network interaction
-// in case the user manages to open this profile with a normal browser UI (i.e.,
-// not headless with the meek-http-helper extension running). Port 9 is
-// "discard", so it should work as a blackhole whether the port is open or
-// closed. network.proxy.type=1 means "Manual proxy configuration".
-// http://kb.mozillazine.org/Network.proxy.type
-user_pref("network.proxy.type", 1);
-user_pref("network.proxy.socks", "127.0.0.1");
-user_pref("network.proxy.socks_port", 9);
-// Make sure DNS is also blackholed. network.proxy.socks_remote_dns is
-// overridden by meek-http-helper at startup.
-user_pref("network.proxy.socks_remote_dns", true);
-
-user_pref("extensions.enabledAddons", "meek-http-helper@bamsoftware.com:1.0");
-
-// Ensure that distribution extensions (e.g., Tor Launcher) are not copied
-// into the meek-http-helper profile.
-user_pref("extensions.installDistroAddons", false);
diff --git a/projects/tor-browser/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix b/projects/tor-browser/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix
index 7192231..18b8460 100644
--- a/projects/tor-browser/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/windows/torrc-defaults-appendix
@@ -1,5 +1,2 @@
## obfs4proxy configuration
-ClientTransportPlugin obfs2,obfs3,obfs4,scramblesuit exec TorBrowser\Tor\PluggableTransports\obfs4proxy.exe
-
-## meek configuration
-ClientTransportPlugin meek exec TorBrowser\Tor\PluggableTransports\terminateprocess-buffer.exe TorBrowser\Tor\PluggableTransports\meek-client-torbrowser.exe -- TorBrowser\Tor\PluggableTransports\meek-client.exe
+ClientTransportPlugin meek_lite,obfs2,obfs3,obfs4,scramblesuit exec TorBrowser\Tor\PluggableTransports\obfs4proxy.exe
diff --git a/projects/tor-browser/build b/projects/tor-browser/build
index f728612..aeb77de 100644
--- a/projects/tor-browser/build
+++ b/projects/tor-browser/build
@@ -26,7 +26,6 @@ touch "$GENERATEDPREFSPATH"
EXTSPATH=Contents/Resources/distribution/extensions
TORBINPATH=Contents/MacOS/Tor
TORCONFIGPATH=Contents/Resources/TorBrowser/Tor
- MEEKPROFILEPATH=Contents/Resources/TorBrowser/Tor/PluggableTransports/template-profile.meek-http-helper
tar -C /var/tmp/dist -xf $rootdir/[% c('input_files_by_name/libdmg') %]
export PATH=/var/tmp/dist/libdmg-hfsplus:$PATH
@@ -36,14 +35,11 @@ touch "$GENERATEDPREFSPATH"
DOCSPATH=TorBrowser/Docs
EXTSPATH=TorBrowser/Data/Browser/profile.default/extensions
TORCONFIGPATH=TorBrowser/Data/Tor
- MEEKPROFILEPATH=TorBrowser/Data/Browser/profile.meek-http-helper
- MOATPROFILEPATH=TorBrowser/Data/Browser/profile.moat-http-helper
mkdir -p "$TBDIR/TorBrowser/Data/Browser/Caches"
[% END %]
mkdir -p "$TBDIR/$EXTSPATH"
-mkdir -p "$TBDIR/$MEEKPROFILEPATH/extensions"
# Extract the MAR tools.
unzip -d $rootdir $rootdir/[% c('input_files_by_name/firefox') %]/mar-tools-*.zip
@@ -53,8 +49,6 @@ mv [% c('input_files_by_name/https-everywhere') %] "$TBDIR/$EXTSPATH/https-every
mv [% c('input_files_by_name/noscript') %] "$TBDIR/$EXTSPATH/{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi"
tar -C "$TBDIR" -xf [% c('input_files_by_name/obfs4') %]
-tar -C "$TBDIR" -xf [% c('input_files_by_name/meek') %]
-mv "$TBDIR/meek-http-helper(a)bamsoftware.com.xpi" "$TBDIR/$MEEKPROFILEPATH/extensions/"
[% IF c("var/snowflake") %]
tar -C "$TBDIR" -xf [% c('input_files_by_name/snowflake') -%]
[% END -%]
@@ -127,23 +121,6 @@ cat Bundle-Data/PTConfigs/[% bundledata_osname %]/torrc-defaults-appendix >> "$T
grep -v 'default_bridge\.snowflake' Bundle-Data/PTConfigs/bridge_prefs.js \
>> "$GENERATEDPREFSPATH"
[% END -%]
-cat Bundle-Data/PTConfigs/meek-http-helper-user.js >> "$TBDIR/$MEEKPROFILEPATH/user.js"
-
-[% IF c("var/osx") %]
- pushd "$TBDIR"
- # Create the meek-template-sha256sum.txt file by generating a list
- # of hashes (one for each file within the meek-http-helper profile) and
- # and then generating one final hash from the contents of the list.
- sha256sum `find $MEEKPROFILEPATH -type f | sort` | sha256sum | sed -e 's/ *-$//' > $MEEKPROFILEPATH/meek-template-sha256sum.txt
- popd
-[% END %]
-
-# For platforms for which we need to ship a Moat helper profile in addition
-# to a meek one, create it by duplicating the meek one that we just finished
-# creating.
-if [ ! -z "$MOATPROFILEPATH" ]; then
- cp -pR $TBDIR/$MEEKPROFILEPATH $TBDIR/$MOATPROFILEPATH
-fi
[% IF ! c("var/multi_lingual") %]
echo 'pref("extensions.torlauncher.prompt_for_locale", false);' >> "$GENERATEDPREFSPATH"
diff --git a/projects/tor-browser/config b/projects/tor-browser/config
index cf8fcb3..e207626 100644
--- a/projects/tor-browser/config
+++ b/projects/tor-browser/config
@@ -65,9 +65,6 @@ input_files:
- project: fonts
name: fonts
enable: '[% ! c("var/android") %]'
- - project: meek
- name: meek
- enable: '[% ! c("var/android") %]'
- project: obfs4
name: obfs4
enable: '[% ! c("var/android") %]'
1
0

[tor-browser-build/master] Merge remote-tracking branch 'pc/bug29430-02'
by gkï¼ torproject.org 28 Aug '19
by gkï¼ torproject.org 28 Aug '19
28 Aug '19
commit 0a7bef243d182fb3df3d9f6ebfd74ce632ad95d1
Merge: 89e6eed f022ea6
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 28 07:10:41 2019 +0000
Merge remote-tracking branch 'pc/bug29430-02'
projects/goutls/config | 2 ++
projects/goutls/sessionid.patch | 25 +++++++++++++
projects/meek/build | 42 ----------------------
projects/meek/config | 17 ---------
projects/obfs4/build | 6 ++--
projects/obfs4/config | 2 +-
.../Docs/Licenses/PluggableTransports/LICENSE | 9 -----
.../Bundle-Data/PTConfigs/bridge_prefs.js | 2 +-
.../PTConfigs/linux/torrc-defaults-appendix | 5 +--
.../mac/TorBrowser.app.meek-http-helper/README | 13 -------
.../PTConfigs/mac/torrc-defaults-appendix | 5 +--
.../Bundle-Data/PTConfigs/meek-http-helper-user.js | 38 --------------------
.../PTConfigs/windows/torrc-defaults-appendix | 5 +--
projects/tor-browser/build | 23 ------------
projects/tor-browser/config | 3 --
15 files changed, 35 insertions(+), 162 deletions(-)
diff --cc projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
index 3405a53,566de2e..de9f98b
--- a/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
+++ b/projects/tor-browser/Bundle-Data/PTConfigs/bridge_prefs.js
@@@ -3,16 -3,17 +3,16 @@@ pref("extensions.torlauncher.default_br
// Default bridges.
pref("extensions.torlauncher.default_bridge.obfs4.1", "obfs4 192.95.36.142:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.2", "obfs4 85.17.30.79:443 FC259A04A328A07FED1413E9FC6526530D9FD87A cert=RutxZlu8BtyP+y0NX7bAVD41+J/qXNhHUrKjFkRSdiBAhIHIQLhKQ2HxESAKZprn/lR3KA iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.3", "obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1");
-/**/pref/**/(/**/"extensions.torlauncher.default_bridge.obfs4.4"/**/, /**/"obfs4 38.229.33.83:80 0BAC39417268B96B9F514E7F63FA6FBA1A788955 cert=VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1OpbAH0wNqOT6H6BmRQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.5", "obfs4 [2001:470:b381:bfff:216:3eff:fe23:d6c3]:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.6", "obfs4 37.218.240.34:40035 88CD36D45A35271963EF82E511C8827A24730913 cert=eGXYfWODcgqIdPJ+rRupg4GGvVGfh25FWaIXZkit206OSngsp7GAIiGIXOJJROMxEqFKJg iat-mode=1");
-pref("extensions.torlauncher.default_bridge.obfs4.7", "obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.8", "obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.9", "obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.10", "obfs4 216.252.162.21:46089 0DB8799466902192B6C7576D58D4F7F714EC87C1 cert=XPUwcQPxEXExHfJYX58gZXN7mYpos7VNAHbkgERNFg+FCVNzuYo1Wp+uMscl3aR9hO2DRQ iat-mode=0");
-pref("extensions.torlauncher.default_bridge.obfs4.11", "obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.2", "obfs4 38.229.1.78:80 C8CBDB2464FC9804A69531437BCF2BE31FDD2EE4 cert=Hmyfd2ev46gGY7NoVxA9ngrPF2zCZtzskRTzoWXbxNkzeVnGFPWmrTtILRyqCTjHR+s9dg iat-mode=1");
+/**/pref/**/(/**/"extensions.torlauncher.default_bridge.obfs4.3"/**/, /**/"obfs4 38.229.33.83:80 0BAC39417268B96B9F514E7F63FA6FBA1A788955 cert=VwEFpk9F/UN9JED7XpG1XOjm/O8ZCXK80oPecgWnNDZDv5pdkhq1OpbAH0wNqOT6H6BmRQ iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.4", "obfs4 [2001:470:b381:bfff:216:3eff:fe23:d6c3]:443 CDF2E852BF539B82BD10E27E9115A31734E378C2 cert=qUVQ0srL1JI/vO6V6m/24anYXiJD3QP2HgzUKQtQ7GRqqUvs7P+tG43RtAqdhLOALP7DJQ iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.5", "obfs4 37.218.240.34:40035 88CD36D45A35271963EF82E511C8827A24730913 cert=eGXYfWODcgqIdPJ+rRupg4GGvVGfh25FWaIXZkit206OSngsp7GAIiGIXOJJROMxEqFKJg iat-mode=1");
+pref("extensions.torlauncher.default_bridge.obfs4.6", "obfs4 37.218.245.14:38224 D9A82D2F9C2F65A18407B1D2B764F130847F8B5D cert=bjRaMrr1BRiAW8IE9U5z27fQaYgOhX1UCmOpg2pFpoMvo6ZgQMzLsaTzzQNTlm7hNcb+Sg iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.7", "obfs4 85.31.186.98:443 011F2599C0E9B27EE74B353155E244813763C3E5 cert=ayq0XzCwhpdysn5o0EyDUbmSOx3X/oTEbzDMvczHOdBJKlvIdHHLJGkZARtT4dcBFArPPg iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.8", "obfs4 85.31.186.26:443 91A6354697E6B02A386312F68D82CF86824D3606 cert=PBwr+S8JTVZo6MPdHnkTwXJPILWADLqfMGoVvhZClMq/Urndyd42BwX9YFJHZnBB3H0XCw iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.9", "obfs4 216.252.162.21:46089 0DB8799466902192B6C7576D58D4F7F714EC87C1 cert=XPUwcQPxEXExHfJYX58gZXN7mYpos7VNAHbkgERNFg+FCVNzuYo1Wp+uMscl3aR9hO2DRQ iat-mode=0");
+pref("extensions.torlauncher.default_bridge.obfs4.10", "obfs4 144.217.20.138:80 FB70B257C162BF1038CA669D568D76F5B7F0BABB cert=vYIV5MgrghGQvZPIi1tJwnzorMgqgmlKaB77Y3Z9Q/v94wZBOAXkW+fdx4aSxLVnKO+xNw iat-mode=0");
- pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
+ pref("extensions.torlauncher.default_bridge.meek-azure.1", "meek_lite 0.0.2.0:2 97700DFE9F483596DDA6264C4D7DF7641E1E39CE url=https://meek.azureedge.net/ front=ajax.aspnetcdn.com");
pref("extensions.torlauncher.default_bridge.snowflake.1", "snowflake 0.0.3.0:1 2B280B23E1107BB62ABFC40DDCC8824814F80A72");
1
0

28 Aug '19
commit fce9dc2c0564dfc6bcd6d77f6ae17bac3d02f90d
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 28 07:04:55 2019 +0000
Pick up new tor stable version
---
projects/tor/config | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/projects/tor/config b/projects/tor/config
index 3da5057..63a2da6 100644
--- a/projects/tor/config
+++ b/projects/tor/config
@@ -1,6 +1,6 @@
# vim: filetype=yaml sw=2
filename: '[% project %]-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %]'
-version: 0.4.0.5
+version: 0.4.1.5
git_hash: 'tor-[% c("version") %]'
git_url: https://git.torproject.org/tor.git
git_submodule: 1
1
0

[torbutton/master] Merge remote-tracking branch 'pearl/bug29430-01'
by gkï¼ torproject.org 28 Aug '19
by gkï¼ torproject.org 28 Aug '19
28 Aug '19
commit 605decfd4ddc81eb37da17172f48f92fd7f7e451
Merge: f4530dc7 84469348
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Aug 28 06:40:19 2019 +0000
Merge remote-tracking branch 'pearl/bug29430-01'
modules/tor-control-port.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
1
0

[torbutton/master] Bug 29430: Use obfs4proxy's meek_lite with utls instead of meek
by gkï¼ torproject.org 28 Aug '19
by gkï¼ torproject.org 28 Aug '19
28 Aug '19
commit 844693481ce92bb34536113a318211cbaedde4bd
Author: Kathy Brade <brade(a)pearlcrescent.com>
Date: Tue Aug 27 16:28:16 2019 -0400
Bug 29430: Use obfs4proxy's meek_lite with utls instead of meek
Add support for meek_lite bridges to bridgeParser. This fixes a
problem where the circuit display broke when a meek_lite bridge
was used.
---
modules/tor-control-port.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/tor-control-port.js b/modules/tor-control-port.js
index afb3d606..6e310b52 100644
--- a/modules/tor-control-port.js
+++ b/modules/tor-control-port.js
@@ -472,7 +472,7 @@ info.bridgeParser = function(bridgeLine) {
// Several bridge types have a similar format:
} else {
result.type = tokens[0];
- if (["flashproxy", "fte", "meek", "obfs3", "obfs4", "scramblesuit",
+ if (["flashproxy", "fte", "meek", "meek_lite", "obfs3", "obfs4", "scramblesuit",
"snowflake"].indexOf(result.type) >= 0) {
[result.address, result.ID] = tokens.slice(1);
}
1
0

28 Aug '19
commit f4530dc77da1a2c204674be33797d399c2bf597c
Merge: 133eb64a 2e3a4b9d
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 12:19:21 2019 +0000
Merge remote-tracking branch 'acat/31322'
chrome/content/aboutTor/aboutTor.xhtml | 1 +
1 file changed, 1 insertion(+)
1
0

[torbutton/master] Bug 31322: Fix about:tor assertion failure debug builds
by gkï¼ torproject.org 28 Aug '19
by gkï¼ torproject.org 28 Aug '19
28 Aug '19
commit 2e3a4b9d7b09dba2dede3aa5e89854b1029b73a5
Author: Alex Catarineu <acat(a)torproject.org>
Date: Tue Aug 6 15:47:59 2019 +0200
Bug 31322: Fix about:tor assertion failure debug builds
Adding a CSP policy to about:tor to address a failed assertion.
---
chrome/content/aboutTor/aboutTor.xhtml | 1 +
1 file changed, 1 insertion(+)
diff --git a/chrome/content/aboutTor/aboutTor.xhtml b/chrome/content/aboutTor/aboutTor.xhtml
index 0789f851..2b75debc 100644
--- a/chrome/content/aboutTor/aboutTor.xhtml
+++ b/chrome/content/aboutTor/aboutTor.xhtml
@@ -20,6 +20,7 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
+ <meta http-equiv="Content-Security-Policy" content="default-src chrome: resource:; script-src chrome: 'unsafe-inline';" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>&aboutTor.title;</title>
<link rel="stylesheet" type="text/css" media="all"
1
0

[tor-browser-build/master] Bug 31458: Revert patch for #27503 and update mingw-w64
by gkï¼ torproject.org 28 Aug '19
by gkï¼ torproject.org 28 Aug '19
28 Aug '19
commit 89e6eed8ce459dfeae17ce886f35df209760965c
Author: Richard Pospesel <richard(a)torproject.org>
Date: Thu Aug 22 15:40:07 2019 -0700
Bug 31458: Revert patch for #27503 and update mingw-w64
The WIDL fixes landed on mingw-w64 master and we can avoid shipping them
separately now.
---
projects/mingw-w64/27503.patch | 10582 ---------------------------------------
projects/mingw-w64/build | 3 -
projects/mingw-w64/config | 3 +-
3 files changed, 1 insertion(+), 10587 deletions(-)
diff --git a/projects/mingw-w64/27503.patch b/projects/mingw-w64/27503.patch
deleted file mode 100644
index ca542d0..0000000
--- a/projects/mingw-w64/27503.patch
+++ /dev/null
@@ -1,10582 +0,0 @@
-diff --git a/mingw-w64-tools/widl/src/client.c b/mingw-w64-tools/widl/src/client.c
-index a3b2bbb6..d27c6cad 100644
---- a/mingw-w64-tools/widl/src/client.c
-+++ b/mingw-w64-tools/widl/src/client.c
-@@ -20,7 +20,7 @@
-
- #include "config.h"
- #include "wine/port.h"
--
-+
- #include <stdio.h>
- #include <stdlib.h>
- #ifdef HAVE_UNISTD_H
-@@ -34,7 +34,7 @@
- #include "parser.h"
- #include "header.h"
-
--#include "widltypes.h"
-+#include "typetree.h"
- #include "typegen.h"
- #include "expr.h"
-
-@@ -52,12 +52,13 @@ 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_function_get_args(func->declspec.type);
-+ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
-
- if (!callconv) callconv = "__cdecl";
-- write_type_decl_left(client, rettype);
-+ write_declspec_decl_left(client, retdeclspec);
-+ if (func->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(client, " inline");
- fprintf(client, " %s ", callconv);
- fprintf(client, "%s%s(\n", prefix_client, get_name(func));
- indent++;
-@@ -74,9 +75,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 +98,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 +137,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_declspec_decl(client, &retval->declspec, retval->name);
- fprintf(client, ";\n");
- }
- print_client("RPC_MESSAGE _RpcMessage;\n");
-@@ -147,7 +148,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 +195,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 +258,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);
- }
-@@ -291,7 +292,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
- const char *func_name, const char *ret_type)
- {
- enum stub_mode mode = get_stub_mode();
-- static int emited_pickling_info;
-+ static int emitted_pickling_info;
-
- if (iface && !type->typestring_offset)
- {
-@@ -301,7 +302,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
- return;
- }
-
-- if (!emited_pickling_info && iface && mode != MODE_Os)
-+ if (!emitted_pickling_info && iface && mode != MODE_Os)
- {
- fprintf(file, "static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =\n");
- fprintf(file, "{\n");
-@@ -312,7 +313,7 @@ static void write_serialize_function(FILE *file, const type_t *type, const type_
- fprintf(file, " 0\n");
- fprintf(file, "};\n");
- fprintf(file, "\n");
-- emited_pickling_info = 1;
-+ emitted_pickling_info = 1;
- }
-
- /* FIXME: Assuming explicit handle */
-@@ -365,8 +366,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 );
-@@ -425,7 +426,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
- print_client("1, /* -error bounds_check flag */\n");
- print_client("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
- print_client("0,\n");
-- print_client("0x50100a4, /* MIDL Version 5.1.164 */\n");
-+ print_client("0x50200ca, /* MIDL Version 5.2.202 */\n");
- print_client("0,\n");
- print_client("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
- print_client("0, /* notify & notify_flag routine table */\n");
-@@ -488,7 +489,7 @@ static void write_implicithandledecl(type_t *iface)
-
- if (implicit_handle)
- {
-- write_type_decl( client, implicit_handle->type, implicit_handle->name );
-+ write_declspec_decl( client, &implicit_handle->declspec, implicit_handle->name );
- fprintf(client, ";\n\n");
- }
- }
-@@ -532,8 +533,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;
-@@ -627,26 +628,6 @@ void write_client(const statement_list_t *stmts)
- if (!client)
- return;
-
-- if (do_win32 && do_win64)
-- {
-- fprintf(client, "#ifndef _WIN64\n\n");
-- pointer_size = 4;
-- write_client_routines( stmts );
-- fprintf(client, "\n#else /* _WIN64 */\n\n");
-- pointer_size = 8;
-- write_client_routines( stmts );
-- fprintf(client, "\n#endif /* _WIN64 */\n");
-- }
-- else if (do_win32)
-- {
-- pointer_size = 4;
-- write_client_routines( stmts );
-- }
-- else if (do_win64)
-- {
-- pointer_size = 8;
-- write_client_routines( stmts );
-- }
--
-+ write_client_routines( stmts );
- fclose(client);
- }
-diff --git a/mingw-w64-tools/widl/src/expr.c b/mingw-w64-tools/widl/src/expr.c
-index 2ed4aff6..2f075816 100644
---- a/mingw-w64-tools/widl/src/expr.c
-+++ b/mingw-w64-tools/widl/src/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;
-@@ -521,11 +521,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
- break;
- case EXPR_STRLIT:
- result.is_temporary = TRUE;
-- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
-+ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0));
- break;
- case EXPR_WSTRLIT:
- result.is_temporary = TRUE;
-- result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
-+ result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0));
- break;
- case EXPR_CHARCONST:
- result.is_temporary = TRUE;
-@@ -575,15 +575,15 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
- expr_loc->attr ? expr_loc->attr : "");
- result.is_variable = FALSE;
- result.is_temporary = TRUE;
-- result.type = type_new_pointer(FC_UP, result.type, NULL);
-+ result.type = type_new_pointer(FC_UP, result.type);
- break;
- case EXPR_PPTR:
- result = resolve_expression(expr_loc, cont_type, e->ref);
- if (result.type && is_ptr(result.type))
-- result.type = type_pointer_get_ref(result.type);
-+ result.type = type_pointer_get_ref_type(result.type);
- else if(result.type && is_array(result.type)
- && type_array_is_decl_as_ptr(result.type))
-- result.type = type_array_get_element(result.type);
-+ result.type = type_array_get_element_type(result.type);
- else
- error_loc_info(&expr_loc->v->loc_info, "dereference operator applied to non-pointer type in expression%s%s\n",
- expr_loc->attr ? " for attribute " : "",
-@@ -665,7 +665,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
- if (result.type && is_array(result.type))
- {
- struct expression_type index_result;
-- result.type = type_array_get_element(result.type);
-+ result.type = type_array_get_element_type(result.type);
- index_result = resolve_expression(expr_loc, cont_type /* FIXME */, e->u.ext);
- if (!index_result.type || !is_integer_type(index_result.type))
- error_loc_info(&expr_loc->v->loc_info, "array subscript not of integral type in expression%s%s\n",
-diff --git a/mingw-w64-tools/widl/src/header.c b/mingw-w64-tools/widl/src/header.c
-index defc7f85..d0d0dc4b 100644
---- a/mingw-w64-tools/widl/src/header.c
-+++ b/mingw-w64-tools/widl/src/header.c
-@@ -43,7 +43,7 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list);
- context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
- generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
-
--static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name);
-+static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name);
-
- static void indent(FILE *h, int delta)
- {
-@@ -69,15 +69,15 @@ 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))
- return 1;
- else if (type_is_alias(type))
-- type = type_alias_get_aliasee(type);
-+ type = type_alias_get_aliasee_type(type);
- else if (is_ptr(type))
-- type = type_pointer_get_ref(type);
-+ type = type_pointer_get_ref_type(type);
- else return 0;
- }
- }
-@@ -91,7 +91,7 @@ int is_aliaschain_attr(const type_t *type, enum attr_type attr)
- if (is_attr(t->attrs, attr))
- return 1;
- else if (type_is_alias(t))
-- t = type_alias_get_aliasee(t);
-+ t = type_alias_get_aliasee_type(t);
- else return 0;
- }
- }
-@@ -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_v(h, &v->declspec, TRUE, v->declonly, name);
- fprintf(h, ";\n");
- }
- }
-@@ -295,14 +295,21 @@ static void write_pointer_left(FILE *h, type_t *ref)
- }
-
- void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
-+{
-+ decl_spec_t ds;
-+ write_declspec_left(h, init_declspec(&ds, t), name_type, declonly);
-+}
-+
-+void write_declspec_left(FILE* h, const decl_spec_t *ds, enum name_type name_type, int declonly)
- {
- const char *name;
-+ type_t *t = ds->type;
-
- if (!h) return;
-
- name = type_get_name(t, name_type);
-
-- if (is_attr(t->attrs, ATTR_CONST) &&
-+ if ((ds->typequalifier == TYPE_QUALIFIER_CONST) &&
- (type_is_alias(t) || !is_ptr(t)))
- fprintf(h, "const ");
-
-@@ -310,7 +317,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
- else {
- switch (type_get_type_detect_alias(t)) {
- case TYPE_ENUM:
-- if (!declonly && t->defined && !t->written) {
-+ if (!declonly && type_is_defined(t) && !t->written) {
- if (name) fprintf(h, "enum %s {\n", name);
- else fprintf(h, "enum {\n");
- t->written = TRUE;
-@@ -323,7 +330,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
- break;
- case TYPE_STRUCT:
- case TYPE_ENCAPSULATED_UNION:
-- if (!declonly && t->defined && !t->written) {
-+ if (!declonly && type_is_defined(t) && !t->written) {
- if (name) fprintf(h, "struct %s {\n", name);
- else fprintf(h, "struct {\n");
- t->written = TRUE;
-@@ -338,7 +345,7 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
- else fprintf(h, "struct %s", name ? name : "");
- break;
- case TYPE_UNION:
-- if (!declonly && t->defined && !t->written) {
-+ if (!declonly && type_is_defined(t) && !t->written) {
- if (t->name) fprintf(h, "union %s {\n", t->name);
- else fprintf(h, "union {\n");
- t->written = TRUE;
-@@ -351,9 +358,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
- break;
- case TYPE_POINTER:
- {
-- write_type_left(h, type_pointer_get_ref(t), name_type, declonly);
-- write_pointer_left(h, type_pointer_get_ref(t));
-- if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
-+ write_declspec_left(h, type_pointer_get_ref(t), name_type, declonly);
-+ write_pointer_left(h, type_pointer_get_ref_type(t));
-+ if (ds->typequalifier == TYPE_QUALIFIER_CONST) fprintf(h, "const ");
- break;
- }
- case TYPE_ARRAY:
-@@ -361,9 +368,9 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
- fprintf(h, "%s", t->name);
- else
- {
-- write_type_left(h, type_array_get_element(t), name_type, declonly);
-+ write_declspec_left(h, type_array_get_element(t), name_type, declonly);
- if (type_array_is_decl_as_ptr(t))
-- write_pointer_left(h, type_array_get_element(t));
-+ write_pointer_left(h, type_array_get_element_type(t));
- }
- break;
- case TYPE_BASIC:
-@@ -443,7 +450,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
- {
- case TYPE_ARRAY:
- {
-- type_t *elem = type_array_get_element(t);
-+ type_t *elem = type_array_get_element_type(t);
- if (type_array_is_decl_as_ptr(t))
- {
- if (!type_is_alias(elem) && is_array(elem) && !type_array_is_decl_as_ptr(elem))
-@@ -461,7 +468,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
- }
- case TYPE_POINTER:
- {
-- type_t *ref = type_pointer_get_ref(t);
-+ type_t *ref = type_pointer_get_ref_type(t);
- if (!type_is_alias(ref) && is_array(ref) && !type_array_is_decl_as_ptr(ref))
- fprintf(h, ")");
- write_type_right(h, ref, FALSE);
-@@ -485,30 +492,33 @@ void write_type_right(FILE *h, type_t *t, int is_field)
- }
- }
-
--static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const char *name)
-+static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declonly, const char *name)
- {
-+ type_t *t = ds->type;
- type_t *pt = NULL;
- int ptr_level = 0;
-
- if (!h) return;
-
- if (t) {
-- for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++)
-+ const decl_spec_t *dpt = NULL;
-+ for (dpt = ds; is_ptr(dpt->type); dpt = type_pointer_get_ref(dpt->type), ptr_level++)
- ;
-+ pt = dpt->type;
-
- if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) {
- int i;
- const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
- if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE";
-- if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
-- write_type_left(h, type_function_get_rettype(pt), NAME_DEFAULT, declonly);
-+ if (!is_ptr(ds->type) && dpt->funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(h, "inline ");
-+ write_declspec_left(h, type_function_get_retdeclspec(pt), NAME_DEFAULT, declonly);
- fputc(' ', h);
- if (ptr_level) fputc('(', h);
- if (callconv) fprintf(h, "%s ", callconv);
- for (i = 0; i < ptr_level; i++)
- fputc('*', h);
- } else
-- write_type_left(h, t, NAME_DEFAULT, declonly);
-+ write_declspec_left(h, ds, NAME_DEFAULT, declonly);
- }
-
- if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
-@@ -529,12 +539,7 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c
- }
- }
-
--static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name)
--{
-- write_type_v(f, t, field, FALSE, name);
--}
--
--static void write_type_definition(FILE *f, type_t *t)
-+static void write_type_definition(FILE *f, type_t *t, int declonly)
- {
- int in_namespace = t->namespace && !is_global_namespace(t->namespace);
- int save_written = t->written;
-@@ -545,14 +550,14 @@ static void write_type_definition(FILE *f, type_t *t)
- write_namespace_start(f, t->namespace);
- }
- indent(f, 0);
-- write_type_left(f, t, NAME_DEFAULT, FALSE);
-+ write_type_left(f, t, NAME_DEFAULT, declonly);
- fprintf(f, ";\n");
- if(in_namespace) {
- t->written = save_written;
- write_namespace_end(f, t->namespace);
- fprintf(f, "extern \"C\" {\n");
- fprintf(f, "#else\n");
-- write_type_left(f, t, NAME_C, FALSE);
-+ write_type_left(f, t, NAME_C, declonly);
- fprintf(f, ";\n");
- fprintf(f, "#endif\n\n");
- }
-@@ -560,12 +565,18 @@ static void write_type_definition(FILE *f, type_t *t)
-
- void write_type_decl(FILE *f, type_t *t, const char *name)
- {
-- write_type_v(f, t, FALSE, TRUE, name);
-+ decl_spec_t ds;
-+ write_declspec_decl(f, init_declspec(&ds, t), name);
-+}
-+
-+void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name)
-+{
-+ write_type_v(f, ds, FALSE, TRUE, name);
- }
-
--void write_type_decl_left(FILE *f, type_t *t)
-+void write_declspec_decl_left(FILE *f, const decl_spec_t *ds)
- {
-- write_type_left(f, t, NAME_DEFAULT, TRUE);
-+ write_declspec_left(f, ds, NAME_DEFAULT, TRUE);
- }
-
- static int user_type_registered(const char *name)
-@@ -602,8 +613,8 @@ unsigned int get_context_handle_offset( const type_t *type )
-
- while (!is_attr( type->attrs, ATTR_CONTEXTHANDLE ))
- {
-- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
-- else if (is_ptr( type )) type = type_pointer_get_ref( type );
-+ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
-+ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
- else error( "internal error: %s is not a context handle\n", type->name );
- }
- LIST_FOR_EACH_ENTRY( ch, &context_handle_list, context_handle_t, entry )
-@@ -622,8 +633,8 @@ unsigned int get_generic_handle_offset( const type_t *type )
-
- while (!is_attr( type->attrs, ATTR_HANDLE ))
- {
-- if (type_is_alias( type )) type = type_alias_get_aliasee( type );
-- else if (is_ptr( type )) type = type_pointer_get_ref( type );
-+ if (type_is_alias( type )) type = type_alias_get_aliasee_type( type );
-+ else if (is_ptr( type )) type = type_pointer_get_ref_type( type );
- else error( "internal error: %s is not a generic handle\n", type->name );
- }
- LIST_FOR_EACH_ENTRY( gh, &generic_handle_list, generic_handle_t, entry )
-@@ -637,82 +648,77 @@ unsigned int get_generic_handle_offset( const type_t *type )
-
- /* check for types which require additional prototypes to be generated in the
- * header */
--void check_for_additional_prototype_types(const var_list_t *list)
--{
-- const var_t *v;
--
-- if (!list) return;
-- LIST_FOR_EACH_ENTRY( v, list, const var_t, entry )
-- {
-- type_t *type = v->type;
-- if (!type) continue;
-- for (;;) {
-- const char *name = type->name;
-- if (type->user_types_registered) break;
-- type->user_types_registered = 1;
-- if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
-- if (!context_handle_registered(name))
-- {
-- context_handle_t *ch = xmalloc(sizeof(*ch));
-- ch->name = xstrdup(name);
-- list_add_tail(&context_handle_list, &ch->entry);
-- }
-- /* don't carry on parsing fields within this type */
-- break;
-- }
-- if ((type_get_type(type) != TYPE_BASIC ||
-- type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
-- is_attr(type->attrs, ATTR_HANDLE)) {
-- if (!generic_handle_registered(name))
-- {
-- generic_handle_t *gh = xmalloc(sizeof(*gh));
-- gh->name = xstrdup(name);
-- list_add_tail(&generic_handle_list, &gh->entry);
-- }
-- /* don't carry on parsing fields within this type */
-- break;
-+void check_for_additional_prototype_types(type_t *type)
-+{
-+ if (!type) return;
-+ for (;;) {
-+ const char *name = type->name;
-+ if (type->user_types_registered) break;
-+ type->user_types_registered = 1;
-+ if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) {
-+ if (!context_handle_registered(name))
-+ {
-+ context_handle_t *ch = xmalloc(sizeof(*ch));
-+ ch->name = xstrdup(name);
-+ list_add_tail(&context_handle_list, &ch->entry);
- }
-- if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
-- if (!user_type_registered(name))
-- {
-- user_type_t *ut = xmalloc(sizeof *ut);
-- ut->name = xstrdup(name);
-- list_add_tail(&user_type_list, &ut->entry);
-- }
-- /* don't carry on parsing fields within this type as we are already
-- * using a wire marshaled type */
-- break;
-+ /* don't carry on parsing fields within this type */
-+ break;
-+ }
-+ if ((type_get_type(type) != TYPE_BASIC ||
-+ type_basic_get_type(type) != TYPE_BASIC_HANDLE) &&
-+ is_attr(type->attrs, ATTR_HANDLE)) {
-+ if (!generic_handle_registered(name))
-+ {
-+ generic_handle_t *gh = xmalloc(sizeof(*gh));
-+ gh->name = xstrdup(name);
-+ list_add_tail(&generic_handle_list, &gh->entry);
- }
-- else if (type_is_complete(type))
-+ /* don't carry on parsing fields within this type */
-+ break;
-+ }
-+ if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
-+ if (!user_type_registered(name))
- {
-- var_list_t *vars;
-- switch (type_get_type_detect_alias(type))
-- {
-- case TYPE_ENUM:
-- vars = type_enum_get_values(type);
-- break;
-- case TYPE_STRUCT:
-- vars = type_struct_get_fields(type);
-- break;
-- case TYPE_UNION:
-- vars = type_union_get_cases(type);
-- break;
-- default:
-- vars = NULL;
-- break;
-- }
-- check_for_additional_prototype_types(vars);
-+ user_type_t *ut = xmalloc(sizeof *ut);
-+ ut->name = xstrdup(name);
-+ list_add_tail(&user_type_list, &ut->entry);
- }
--
-- if (type_is_alias(type))
-- type = type_alias_get_aliasee(type);
-- else if (is_ptr(type))
-- type = type_pointer_get_ref(type);
-- else if (is_array(type))
-- type = type_array_get_element(type);
-- else
-+ /* don't carry on parsing fields within this type as we are already
-+ * using a wire marshaled type */
-+ break;
-+ }
-+ else if (type_is_complete(type))
-+ {
-+ var_list_t *vars;
-+ const var_t *v;
-+ switch (type_get_type_detect_alias(type))
-+ {
-+ case TYPE_ENUM:
-+ vars = type_enum_get_values(type);
-+ break;
-+ case TYPE_STRUCT:
-+ vars = type_struct_get_fields(type);
- break;
-+ case TYPE_UNION:
-+ vars = type_union_get_cases(type);
-+ break;
-+ default:
-+ vars = NULL;
-+ break;
-+ }
-+ if (vars) LIST_FOR_EACH_ENTRY( v, vars, const var_t, entry )
-+ check_for_additional_prototype_types(v->declspec.type);
- }
-+
-+ if (type_is_alias(type))
-+ type = type_alias_get_aliasee_type(type);
-+ else if (is_ptr(type))
-+ type = type_pointer_get_ref_type(type);
-+ else if (is_array(type))
-+ type = type_array_get_element_type(type);
-+ else
-+ break;
- }
- }
-
-@@ -791,26 +797,26 @@ static void write_generic_handle_routines(FILE *header)
- }
- }
-
--static void write_typedef(FILE *header, type_t *type)
-+static void write_typedef(FILE *header, type_t *type, int declonly)
- {
- fprintf(header, "typedef ");
-- write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name);
-+ write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name);
- fprintf(header, ";\n");
- }
-
- int is_const_decl(const var_t *var)
- {
-- const type_t *t;
-+ const decl_spec_t *ds;
- /* strangely, MIDL accepts a const attribute on any pointer in the
- * 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 (ds = &var->declspec; ;)
- {
-- if (is_attr(t->attrs, ATTR_CONST))
-+ if (ds->typequalifier == TYPE_QUALIFIER_CONST)
- return TRUE;
-- else if (is_ptr(t))
-- t = type_pointer_get_ref(t);
-+ else if (is_ptr(ds->type))
-+ ds = type_pointer_get_ref(ds->type);
- else break;
- }
- return FALSE;
-@@ -826,7 +832,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 */
-@@ -838,7 +844,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_v(header, &v->declspec, FALSE, FALSE, v->name);
- fprintf(header, ";\n\n");
- }
- }
-@@ -855,9 +861,9 @@ 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))
-+ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
- if ((type_get_type_detect_alias(t) != TYPE_BASIC || type_basic_get_type(t) != TYPE_BASIC_HANDLE) &&
- is_attr(t->attrs, ATTR_HANDLE))
- return t;
-@@ -868,13 +874,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_function_get_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;
-@@ -884,7 +890,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;
-@@ -893,8 +899,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;
-@@ -909,13 +915,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
- if (is_attr(var->attrs, ATTR_OUT))
- return 1;
-
-@@ -995,7 +1001,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;
- }
-@@ -1035,8 +1041,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_function_get_args(func->declspec.type))
-+ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
- fprintf(header, ",%s", arg->name);
- fprintf(header, ") ");
-
-@@ -1047,8 +1053,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_function_get_args(func->declspec.type))
-+ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
- fprintf(header, ",%s", arg->name);
- fprintf(header, ")\n");
- }
-@@ -1078,7 +1084,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_declspec_decl(h, &arg->declspec, arg->name);
- if (method == 2) {
- const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE);
- if (expr) {
-@@ -1090,7 +1096,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;
-@@ -1119,8 +1125,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_function_get_args(func->declspec.type);
- const var_t *arg;
-
- if (!callconv) callconv = "STDMETHODCALLTYPE";
-@@ -1130,11 +1136,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_declspec_decl_left(header, type_function_get_retdeclspec(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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
- fprintf(header, " *__ret");
- --indentation;
- if (args) {
-@@ -1144,7 +1150,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
- fprintf(header, " %s %s(\n", callconv, get_name(func));
- write_args(header, args, iface->name, 2, TRUE);
- fprintf(header, ")\n");
-@@ -1152,7 +1158,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
- fprintf(header, " __ret;\n");
- indent(header, 0);
- fprintf(header, "return *%s(&__ret", get_name(func));
-@@ -1169,7 +1175,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
- fprintf(header, " %s %s(\n", callconv, get_name(func));
- write_args(header, args, iface->name, 2, TRUE);
- fprintf(header, ") = 0;\n");
-@@ -1206,25 +1212,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_declspec_decl_left(header, type_function_get_retdeclspec(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_function_get_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_declspec_decl_left(header, type_function_get_retdeclspec(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_function_get_args(func->declspec.type))
-+ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), const var_t, entry )
- fprintf(header, ",%s", arg->name);
- fprintf(header, ");\n");
- --indentation;
-@@ -1250,10 +1256,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
- if (is_aggregate_return(func))
- fprintf(header, " *");
- if (is_inherited_method(iface, func))
-@@ -1266,13 +1272,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_declspec_decl_left(header, type_function_get_retdeclspec(func->declspec.type));
- fprintf(header, " *__ret");
- }
- --indentation;
-- if (type_get_function_args(func->type)) {
-+ if (type_function_get_args(func->declspec.type)) {
- fprintf(header, ",\n");
-- write_args(header, type_get_function_args(func->type), name, 0, TRUE);
-+ write_args(header, type_function_get_args(func->declspec.type), name, 0, TRUE);
- }
- fprintf(header, ");\n");
- fprintf(header, "\n");
-@@ -1299,12 +1305,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_declspec_decl_left(header, type_function_get_retdeclspec(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_function_get_args(func->declspec.type), iface->name, 1, TRUE);
- fprintf(header, ");\n");
- /* stub prototype */
- fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func));
-@@ -1337,12 +1343,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_declspec_decl_left(fp, type_function_get_retdeclspec(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_function_get_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)
-@@ -1359,9 +1365,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_declspec_decl_left(fp, type_function_get_retdeclspec(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_function_get_args(func->declspec.type), iface->name, 1, TRUE);
- fprintf(fp, ")");
- if (body)
- /* Remotable methods must all return HRESULTs. */
-@@ -1407,15 +1413,16 @@ 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_declspec_decl_left(header, type_function_get_retdeclspec(fun->declspec.type));
-+ if (fun->declspec.funcspecifier == FUNCTION_SPECIFIER_INLINE) fprintf(header, " inline");
- 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_function_get_args(fun->declspec.type))
-+ write_args(header, type_function_get_args(fun->declspec.type), iface->name, 0, TRUE);
- else
- fprintf(header, " void");
- fprintf(header, ");\n\n");
-@@ -1541,7 +1548,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_declspec_decl( header, &var->declspec, var->name );
- fprintf(header, ";\n");
- }
- if (old_names)
-@@ -1653,6 +1660,7 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
- if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
- {
- type_t *iface = stmt->u.type;
-+ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
- if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
- {
- write_forward(header, iface);
-@@ -1694,6 +1702,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
- {
- type_t *iface = stmt->u.type;
- type_t *async_iface = iface->details.iface->async_iface;
-+ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
- if (is_object(iface)) is_object_interface++;
- if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
- {
-@@ -1718,7 +1727,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
- write_coclass(header, stmt->u.type);
- else
- {
-- write_type_definition(header, stmt->u.type);
-+ write_type_definition(header, stmt->u.type, stmt->declonly);
- }
- break;
- case STMT_TYPEREF:
-@@ -1739,7 +1748,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
- {
- const type_list_t *type_entry = stmt->u.type_list;
- for (; type_entry; type_entry = type_entry->next)
-- write_typedef(header, type_entry->type);
-+ write_typedef(header, type_entry->type, stmt->declonly);
- break;
- }
- case STMT_LIBRARY:
-@@ -1750,7 +1759,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)
- {
-@@ -1784,15 +1793,15 @@ void write_header(const statement_list_t *stmts)
- }
- fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
-
-+ fprintf(header, "#ifdef _WIN32\n");
- fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n");
- fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\n");
-- fprintf(header, "#endif\n\n");
--
-+ fprintf(header, "#endif\n");
- fprintf(header, "#include <rpc.h>\n" );
- fprintf(header, "#include <rpcndr.h>\n" );
- if (!for_each_serializable(stmts, NULL, serializable_exists))
- fprintf(header, "#include <midles.h>\n" );
-- fprintf(header, "\n" );
-+ fprintf(header, "#endif\n\n");
-
- fprintf(header, "#ifndef COM_NO_WINDOWS_H\n");
- fprintf(header, "#include <windows.h>\n");
-diff --git a/mingw-w64-tools/widl/src/header.h b/mingw-w64-tools/widl/src/header.h
-index 0d44b403..0e62f77c 100644
---- a/mingw-w64-tools/widl/src/header.h
-+++ b/mingw-w64-tools/widl/src/header.h
-@@ -29,10 +29,12 @@ extern int is_attr(const attr_list_t *list, enum attr_type t);
- extern void *get_attrp(const attr_list_t *list, enum attr_type t);
- extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
- extern const char* get_name(const var_t *v);
-+extern void write_declspec_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly);
- extern void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly);
- extern void write_type_right(FILE *h, type_t *t, int is_field);
- extern void write_type_decl(FILE *f, type_t *t, const char *name);
--extern void write_type_decl_left(FILE *f, type_t *t);
-+extern void write_declspec_decl(FILE *f, const decl_spec_t *ds, const char *name);
-+extern void write_declspec_decl_left(FILE *f, const decl_spec_t *ds);
- extern unsigned int get_context_handle_offset( const type_t *type );
- extern unsigned int get_generic_handle_offset( const type_t *type );
- extern int needs_space_after(type_t *t);
-@@ -83,12 +85,12 @@ static inline int is_conformant_array(const type_t *t)
-
- static inline int last_ptr(const type_t *type)
- {
-- return is_ptr(type) && !is_declptr(type_pointer_get_ref(type));
-+ return is_ptr(type) && !is_declptr(type_pointer_get_ref_type(type));
- }
-
- static inline int last_array(const type_t *type)
- {
-- return is_array(type) && !is_array(type_array_get_element(type));
-+ return is_array(type) && !is_array(type_array_get_element_type(type));
- }
-
- static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
-@@ -102,7 +104,7 @@ static inline int is_context_handle(const type_t *type)
- const type_t *t;
- for (t = type;
- is_ptr(t) || type_is_alias(t);
-- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
-+ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
- if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
- return 1;
- return 0;
-diff --git a/mingw-w64-tools/widl/src/parser.tab.c b/mingw-w64-tools/widl/src/parser.tab.c
-index 6266e054..8cd1605a 100644
---- a/mingw-w64-tools/widl/src/parser.tab.c
-+++ b/mingw-w64-tools/widl/src/parser.tab.c
-@@ -1,8 +1,8 @@
--/* A Bison parser, made by GNU Bison 3.0.5. */
-+/* A Bison parser, made by GNU Bison 3.0.4. */
-
- /* Bison implementation for Yacc-like parsers in C
-
-- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
-+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
-@@ -44,7 +44,7 @@
- #define YYBISON 1
-
- /* Bison version. */
--#define YYBISON_VERSION "3.0.5"
-+#define YYBISON_VERSION "3.0.4"
-
- /* Skeleton name. */
- #define YYSKELETON_NAME "yacc.c"
-@@ -125,13 +125,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);
-@@ -140,7 +133,7 @@ static void fix_incomplete_types(type_t *complete_type);
- static str_list_t *append_str(str_list_t *list, char *str);
- static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
- static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
--static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
-+static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
- static attr_t *make_attr(enum attr_type type);
- static attr_t *make_attrv(enum attr_type type, unsigned int val);
- static attr_t *make_attrp(enum attr_type type, void *val);
-@@ -156,6 +149,7 @@ static declarator_t *make_declarator(var_t *var);
- static type_t *make_safearray(type_t *type);
- static typelib_t *make_library(const char *name, const attr_list_t *attrs);
- static type_t *append_chain_type(type_t *chain, type_t *type);
-+static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
- static warning_list_t *append_warning(warning_list_t *, int);
-
- static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
-@@ -212,7 +206,7 @@ static struct namespace *current_namespace = &global_namespace;
- static typelib_t *current_typelib;
-
-
--#line 216 "parser.tab.c" /* yacc.c:339 */
-+#line 210 "parser.tab.c" /* yacc.c:339 */
-
- # ifndef YY_NULLPTR
- # if defined __cplusplus && 201103L <= __cplusplus
-@@ -438,7 +432,7 @@ extern int parser_debug;
-
- union YYSTYPE
- {
--#line 142 "parser.y" /* yacc.c:355 */
-+#line 136 "parser.y" /* yacc.c:355 */
-
- attr_t *attr;
- attr_list_t *attr_list;
-@@ -465,8 +459,10 @@ union YYSTYPE
- struct _import_t *import;
- struct _decl_spec_t *declspec;
- enum storage_class stgclass;
-+ enum type_qualifier typequalifier;
-+ enum function_specifier funcspecifier;
-
--#line 470 "parser.tab.c" /* yacc.c:355 */
-+#line 466 "parser.tab.c" /* yacc.c:355 */
- };
-
- typedef union YYSTYPE YYSTYPE;
-@@ -483,7 +479,7 @@ int parser_parse (void);
-
- /* Copy the second part of user declarations. */
-
--#line 487 "parser.tab.c" /* yacc.c:358 */
-+#line 483 "parser.tab.c" /* yacc.c:358 */
-
- #ifdef short
- # undef short
-@@ -799,48 +795,48 @@ static const yytype_uint8 yytranslate[] =
- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
- static const yytype_uint16 yyrline[] =
- {
-- 0, 325, 325, 340, 340, 342, 343, 343, 345, 346,
-- 347, 350, 353, 354, 355, 358, 359, 360, 360, 362,
-- 363, 364, 367, 368, 369, 370, 373, 374, 377, 378,
-- 382, 383, 384, 385, 386, 387, 388, 391, 402, 403,
-- 407, 408, 409, 410, 411, 412, 413, 414, 415, 418,
-- 420, 428, 434, 438, 439, 441, 445, 449, 450, 453,
-- 454, 457, 458, 462, 467, 474, 478, 479, 482, 483,
-- 487, 490, 491, 492, 495, 496, 499, 500, 501, 502,
-- 503, 504, 505, 506, 507, 508, 509, 510, 511, 512,
-- 513, 514, 515, 516, 517, 518, 519, 520, 521, 522,
-- 523, 524, 525, 526, 527, 528, 529, 530, 531, 532,
-- 533, 534, 535, 536, 537, 538, 539, 540, 541, 542,
-- 543, 544, 545, 546, 547, 548, 549, 550, 551, 552,
-- 553, 554, 555, 556, 557, 558, 559, 560, 561, 562,
-- 563, 564, 565, 566, 567, 568, 569, 570, 571, 572,
-- 573, 574, 578, 579, 580, 581, 582, 583, 584, 585,
-- 586, 587, 588, 589, 590, 591, 592, 593, 594, 595,
-- 596, 597, 598, 599, 600, 601, 605, 606, 611, 612,
-- 613, 614, 617, 618, 621, 625, 631, 632, 633, 636,
-- 640, 652, 656, 661, 664, 665, 668, 669, 672, 673,
-- 674, 675, 676, 677, 678, 679, 680, 681, 682, 683,
-- 684, 685, 686, 687, 688, 689, 690, 691, 692, 693,
-- 694, 695, 696, 697, 698, 699, 700, 701, 702, 703,
-- 704, 705, 706, 707, 708, 709, 711, 713, 714, 717,
-- 718, 721, 727, 733, 734, 737, 742, 749, 750, 753,
-- 754, 758, 759, 762, 766, 772, 780, 784, 789, 790,
-- 793, 794, 795, 798, 800, 803, 804, 805, 806, 807,
-- 808, 809, 810, 811, 812, 813, 816, 817, 820, 821,
-- 822, 823, 824, 825, 826, 827, 828, 831, 832, 840,
-- 846, 850, 853, 854, 858, 861, 862, 865, 874, 875,
-- 878, 879, 882, 888, 894, 895, 898, 899, 902, 912,
-- 922, 928, 932, 933, 936, 937, 940, 945, 952, 953,
-- 954, 958, 962, 965, 966, 969, 970, 974, 975, 979,
-- 980, 981, 985, 987, 989, 993, 994, 995, 996, 1004,
-- 1006, 1008, 1013, 1015, 1020, 1021, 1026, 1027, 1028, 1029,
-- 1034, 1043, 1045, 1046, 1051, 1053, 1057, 1058, 1065, 1066,
-- 1067, 1068, 1069, 1074, 1082, 1083, 1086, 1087, 1090, 1097,
-- 1098, 1103, 1104, 1108, 1109, 1110, 1111, 1112, 1116, 1117,
-- 1118, 1121, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131,
-- 1132, 1133, 1136, 1143, 1145, 1151, 1152, 1153, 1156, 1158,
-- 1160, 1162, 1165, 1170, 1178, 1179, 1182, 1183, 1186, 1187,
-- 1188
-+ 0, 323, 323, 338, 338, 340, 341, 341, 343, 344,
-+ 345, 348, 351, 352, 353, 356, 357, 358, 358, 360,
-+ 361, 362, 365, 366, 367, 368, 371, 372, 375, 376,
-+ 380, 381, 382, 383, 384, 385, 386, 389, 400, 401,
-+ 405, 406, 407, 408, 409, 410, 411, 412, 413, 416,
-+ 418, 426, 432, 436, 437, 439, 443, 447, 448, 451,
-+ 452, 455, 456, 460, 465, 472, 476, 477, 480, 481,
-+ 485, 488, 489, 490, 493, 494, 497, 498, 499, 500,
-+ 501, 502, 503, 504, 505, 506, 507, 508, 509, 510,
-+ 511, 512, 513, 514, 515, 516, 517, 518, 519, 520,
-+ 521, 522, 523, 524, 525, 526, 527, 528, 529, 530,
-+ 531, 532, 533, 534, 535, 536, 537, 538, 539, 540,
-+ 541, 542, 543, 544, 545, 546, 547, 548, 549, 550,
-+ 551, 552, 553, 554, 555, 556, 557, 558, 559, 560,
-+ 561, 562, 563, 564, 565, 566, 567, 568, 569, 570,
-+ 571, 572, 576, 577, 578, 579, 580, 581, 582, 583,
-+ 584, 585, 586, 587, 588, 589, 590, 591, 592, 593,
-+ 594, 595, 596, 597, 598, 599, 603, 604, 609, 610,
-+ 611, 612, 615, 616, 619, 623, 629, 630, 631, 634,
-+ 638, 650, 654, 659, 662, 663, 666, 667, 670, 671,
-+ 672, 673, 674, 675, 676, 677, 678, 679, 680, 681,
-+ 682, 683, 684, 685, 686, 687, 688, 689, 690, 691,
-+ 692, 693, 694, 695, 696, 697, 698, 699, 700, 701,
-+ 702, 703, 704, 705, 706, 707, 709, 711, 712, 715,
-+ 716, 719, 725, 731, 732, 735, 740, 747, 748, 751,
-+ 752, 756, 757, 760, 764, 770, 778, 782, 787, 788,
-+ 791, 792, 793, 796, 798, 801, 802, 803, 804, 805,
-+ 806, 807, 808, 809, 810, 811, 814, 815, 818, 819,
-+ 820, 821, 822, 823, 824, 825, 826, 829, 830, 838,
-+ 844, 848, 851, 852, 856, 859, 860, 863, 872, 873,
-+ 876, 877, 880, 886, 892, 893, 896, 897, 900, 910,
-+ 920, 926, 930, 931, 934, 935, 938, 943, 950, 951,
-+ 952, 956, 960, 963, 964, 967, 968, 972, 973, 977,
-+ 978, 979, 983, 985, 987, 991, 992, 993, 994, 1002,
-+ 1004, 1006, 1011, 1013, 1018, 1019, 1024, 1025, 1026, 1027,
-+ 1032, 1041, 1043, 1044, 1049, 1051, 1055, 1056, 1063, 1064,
-+ 1065, 1066, 1067, 1072, 1080, 1081, 1084, 1085, 1088, 1095,
-+ 1096, 1101, 1102, 1106, 1107, 1108, 1109, 1110, 1114, 1115,
-+ 1116, 1119, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129,
-+ 1130, 1131, 1134, 1141, 1143, 1149, 1150, 1151, 1154, 1156,
-+ 1158, 1160, 1163, 1168, 1176, 1177, 1180, 1181, 1184, 1185,
-+ 1186
- };
- #endif
-
-@@ -903,7 +899,7 @@ static const char *const yytname[] =
- "dispinterfacedef", "inherit", "interface", "interfacehdr",
- "interfacedef", "interfacedec", "module", "modulehdr", "moduledef",
- "storage_cls_spec", "function_specifier", "type_qualifier",
-- "m_type_qual_list", "decl_spec", "m_decl_spec_no_type",
-+ "m_type_qual_bits", "decl_spec", "m_decl_spec_no_type",
- "decl_spec_no_type", "declarator", "direct_declarator",
- "abstract_declarator", "abstract_declarator_no_direct",
- "m_abstract_declarator", "abstract_direct_declarator", "any_declarator",
-@@ -2298,7 +2294,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
- case N: \
- yyformat = S; \
- break
-- default: /* Avoid compiler warnings. */
- YYCASE_(0, YY_("syntax error"));
- YYCASE_(1, YY_("syntax error, unexpected %s"));
- YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-@@ -2615,7 +2610,7 @@ yyreduce:
- switch (yyn)
- {
- case 2:
--#line 325 "parser.y" /* yacc.c:1648 */
-+#line 323 "parser.y" /* yacc.c:1646 */
- { fix_incomplete();
- check_statements((yyvsp[-1].stmt_list), FALSE);
- check_all_user_types((yyvsp[-1].stmt_list));
-@@ -2629,197 +2624,197 @@ yyreduce:
- write_dlldata((yyvsp[-1].stmt_list));
- write_local_stubs((yyvsp[-1].stmt_list));
- }
--#line 2633 "parser.tab.c" /* yacc.c:1648 */
-+#line 2628 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 5:
--#line 342 "parser.y" /* yacc.c:1648 */
-+#line 340 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = NULL; }
--#line 2639 "parser.tab.c" /* yacc.c:1648 */
-+#line 2634 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 6:
--#line 343 "parser.y" /* yacc.c:1648 */
-+#line 341 "parser.y" /* yacc.c:1646 */
- { push_namespace((yyvsp[-1].str)); }
--#line 2645 "parser.tab.c" /* yacc.c:1648 */
-+#line 2640 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 7:
--#line 344 "parser.y" /* yacc.c:1648 */
-+#line 342 "parser.y" /* yacc.c:1646 */
- { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
--#line 2651 "parser.tab.c" /* yacc.c:1648 */
-+#line 2646 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 8:
--#line 345 "parser.y" /* yacc.c:1648 */
-+#line 343 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
--#line 2657 "parser.tab.c" /* yacc.c:1648 */
-+#line 2652 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 9:
--#line 346 "parser.y" /* yacc.c:1648 */
-+#line 344 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
--#line 2663 "parser.tab.c" /* yacc.c:1648 */
-+#line 2658 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 10:
--#line 347 "parser.y" /* yacc.c:1648 */
-+#line 345 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = (yyvsp[-2].stmt_list);
- reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0);
- }
--#line 2671 "parser.tab.c" /* yacc.c:1648 */
-+#line 2666 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 11:
--#line 350 "parser.y" /* yacc.c:1648 */
-+#line 348 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
- reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
- }
--#line 2679 "parser.tab.c" /* yacc.c:1648 */
-+#line 2674 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 12:
--#line 353 "parser.y" /* yacc.c:1648 */
-+#line 351 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
--#line 2685 "parser.tab.c" /* yacc.c:1648 */
-+#line 2680 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 13:
--#line 354 "parser.y" /* yacc.c:1648 */
-+#line 352 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
--#line 2691 "parser.tab.c" /* yacc.c:1648 */
-+#line 2686 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 14:
--#line 355 "parser.y" /* yacc.c:1648 */
-+#line 353 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
--#line 2697 "parser.tab.c" /* yacc.c:1648 */
-+#line 2692 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 15:
--#line 358 "parser.y" /* yacc.c:1648 */
-+#line 356 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = NULL; }
--#line 2703 "parser.tab.c" /* yacc.c:1648 */
-+#line 2698 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 16:
--#line 359 "parser.y" /* yacc.c:1648 */
-+#line 357 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); }
--#line 2709 "parser.tab.c" /* yacc.c:1648 */
-+#line 2704 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 17:
--#line 360 "parser.y" /* yacc.c:1648 */
-+#line 358 "parser.y" /* yacc.c:1646 */
- { push_namespace((yyvsp[-1].str)); }
--#line 2715 "parser.tab.c" /* yacc.c:1648 */
-+#line 2710 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 18:
--#line 361 "parser.y" /* yacc.c:1648 */
-+#line 359 "parser.y" /* yacc.c:1646 */
- { pop_namespace((yyvsp[-4].str)); (yyval.stmt_list) = append_statements((yyvsp[-5].stmt_list), (yyvsp[-1].stmt_list)); }
--#line 2721 "parser.tab.c" /* yacc.c:1648 */
-+#line 2716 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 19:
--#line 362 "parser.y" /* yacc.c:1648 */
-+#line 360 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); }
--#line 2727 "parser.tab.c" /* yacc.c:1648 */
-+#line 2722 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 20:
--#line 363 "parser.y" /* yacc.c:1648 */
-+#line 361 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = (yyvsp[-2].stmt_list); reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, current_namespace, 0); }
--#line 2733 "parser.tab.c" /* yacc.c:1648 */
-+#line 2728 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 21:
--#line 364 "parser.y" /* yacc.c:1648 */
-+#line 362 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
- reg_type((yyvsp[0].type), (yyvsp[0].type)->name, current_namespace, 0);
- }
--#line 2741 "parser.tab.c" /* yacc.c:1648 */
-+#line 2736 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 22:
--#line 367 "parser.y" /* yacc.c:1648 */
-+#line 365 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); }
--#line 2747 "parser.tab.c" /* yacc.c:1648 */
-+#line 2742 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 23:
--#line 368 "parser.y" /* yacc.c:1648 */
-+#line 366 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
--#line 2753 "parser.tab.c" /* yacc.c:1648 */
-+#line 2748 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 24:
--#line 369 "parser.y" /* yacc.c:1648 */
-+#line 367 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_importlib((yyvsp[0].str))); }
--#line 2759 "parser.tab.c" /* yacc.c:1648 */
-+#line 2754 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 25:
--#line 370 "parser.y" /* yacc.c:1648 */
-+#line 368 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); }
--#line 2765 "parser.tab.c" /* yacc.c:1648 */
-+#line 2760 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 26:
--#line 373 "parser.y" /* yacc.c:1648 */
-+#line 371 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = NULL; }
--#line 2771 "parser.tab.c" /* yacc.c:1648 */
-+#line 2766 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 27:
--#line 374 "parser.y" /* yacc.c:1648 */
-+#line 372 "parser.y" /* yacc.c:1646 */
- { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); }
--#line 2777 "parser.tab.c" /* yacc.c:1648 */
-+#line 2772 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 30:
--#line 382 "parser.y" /* yacc.c:1648 */
-+#line 380 "parser.y" /* yacc.c:1646 */
- { (yyval.statement) = make_statement_cppquote((yyvsp[0].str)); }
--#line 2783 "parser.tab.c" /* yacc.c:1648 */
-+#line 2778 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 31:
--#line 383 "parser.y" /* yacc.c:1648 */
-+#line 381 "parser.y" /* yacc.c:1646 */
- { (yyval.statement) = make_statement_type_decl((yyvsp[-1].type)); }
--#line 2789 "parser.tab.c" /* yacc.c:1648 */
-+#line 2784 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 32:
--#line 384 "parser.y" /* yacc.c:1648 */
-+#line 382 "parser.y" /* yacc.c:1646 */
- { (yyval.statement) = make_statement_declaration((yyvsp[-1].var)); }
--#line 2795 "parser.tab.c" /* yacc.c:1648 */
-+#line 2790 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 33:
--#line 385 "parser.y" /* yacc.c:1648 */
-+#line 383 "parser.y" /* yacc.c:1646 */
- { (yyval.statement) = make_statement_import((yyvsp[0].str)); }
--#line 2801 "parser.tab.c" /* yacc.c:1648 */
-+#line 2796 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 34:
--#line 386 "parser.y" /* yacc.c:1648 */
-+#line 384 "parser.y" /* yacc.c:1646 */
- { (yyval.statement) = (yyvsp[-1].statement); }
--#line 2807 "parser.tab.c" /* yacc.c:1648 */
-+#line 2802 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 35:
--#line 387 "parser.y" /* yacc.c:1648 */
-+#line 385 "parser.y" /* yacc.c:1646 */
- { (yyval.statement) = make_statement_pragma((yyvsp[0].str)); }
--#line 2813 "parser.tab.c" /* yacc.c:1648 */
-+#line 2808 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 36:
--#line 388 "parser.y" /* yacc.c:1648 */
-+#line 386 "parser.y" /* yacc.c:1646 */
- { (yyval.statement) = NULL; }
--#line 2819 "parser.tab.c" /* yacc.c:1648 */
-+#line 2814 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 37:
--#line 392 "parser.y" /* yacc.c:1648 */
-+#line 390 "parser.y" /* yacc.c:1646 */
- {
- int result;
- (yyval.statement) = NULL;
-@@ -2827,909 +2822,909 @@ yyreduce:
- if(!result)
- error_loc("expected \"disable\" or \"enable\"\n");
- }
--#line 2831 "parser.tab.c" /* yacc.c:1648 */
-+#line 2826 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 38:
--#line 402 "parser.y" /* yacc.c:1648 */
-+#line 400 "parser.y" /* yacc.c:1646 */
- { (yyval.warning_list) = append_warning(NULL, (yyvsp[0].num)); }
--#line 2837 "parser.tab.c" /* yacc.c:1648 */
-+#line 2832 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 39:
--#line 403 "parser.y" /* yacc.c:1648 */
-+#line 401 "parser.y" /* yacc.c:1646 */
- { (yyval.warning_list) = append_warning((yyvsp[-1].warning_list), (yyvsp[0].num)); }
--#line 2843 "parser.tab.c" /* yacc.c:1648 */
-+#line 2838 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 41:
--#line 408 "parser.y" /* yacc.c:1648 */
-+#line 406 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
--#line 2849 "parser.tab.c" /* yacc.c:1648 */
-+#line 2844 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 43:
--#line 410 "parser.y" /* yacc.c:1648 */
-+#line 408 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
--#line 2855 "parser.tab.c" /* yacc.c:1648 */
-+#line 2850 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 45:
--#line 412 "parser.y" /* yacc.c:1648 */
-+#line 410 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
--#line 2861 "parser.tab.c" /* yacc.c:1648 */
-+#line 2856 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 46:
--#line 413 "parser.y" /* yacc.c:1648 */
-+#line 411 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_enum_attrs((yyvsp[-1].attr_list)); }
--#line 2867 "parser.tab.c" /* yacc.c:1648 */
-+#line 2862 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 47:
--#line 414 "parser.y" /* yacc.c:1648 */
-+#line 412 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_struct_attrs((yyvsp[-1].attr_list)); }
--#line 2873 "parser.tab.c" /* yacc.c:1648 */
-+#line 2868 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 48:
--#line 415 "parser.y" /* yacc.c:1648 */
-+#line 413 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type); (yyval.type)->attrs = check_union_attrs((yyvsp[-1].attr_list)); }
--#line 2879 "parser.tab.c" /* yacc.c:1648 */
-+#line 2874 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 49:
--#line 418 "parser.y" /* yacc.c:1648 */
-+#line 416 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[-1].str); }
--#line 2885 "parser.tab.c" /* yacc.c:1648 */
-+#line 2880 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 50:
--#line 420 "parser.y" /* yacc.c:1648 */
-+#line 418 "parser.y" /* yacc.c:1646 */
- { assert(yychar == YYEMPTY);
- (yyval.import) = xmalloc(sizeof(struct _import_t));
- (yyval.import)->name = (yyvsp[-1].str);
- (yyval.import)->import_performed = do_import((yyvsp[-1].str));
- if (!(yyval.import)->import_performed) yychar = aEOF;
- }
--#line 2896 "parser.tab.c" /* yacc.c:1648 */
-+#line 2891 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 51:
--#line 428 "parser.y" /* yacc.c:1648 */
-+#line 426 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[-2].import)->name;
- if ((yyvsp[-2].import)->import_performed) pop_import();
- free((yyvsp[-2].import));
- }
--#line 2905 "parser.tab.c" /* yacc.c:1648 */
-+#line 2900 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 52:
--#line 435 "parser.y" /* yacc.c:1648 */
-+#line 433 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[-2].str); if(!parse_only) add_importlib((yyvsp[-2].str), current_typelib); }
--#line 2911 "parser.tab.c" /* yacc.c:1648 */
-+#line 2906 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 53:
--#line 438 "parser.y" /* yacc.c:1648 */
-+#line 436 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[0].str); }
--#line 2917 "parser.tab.c" /* yacc.c:1648 */
-+#line 2912 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 54:
--#line 439 "parser.y" /* yacc.c:1648 */
-+#line 437 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[0].str); }
--#line 2923 "parser.tab.c" /* yacc.c:1648 */
-+#line 2918 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 55:
--#line 441 "parser.y" /* yacc.c:1648 */
-+#line 439 "parser.y" /* yacc.c:1646 */
- { (yyval.typelib) = make_library((yyvsp[-1].str), check_library_attrs((yyvsp[-1].str), (yyvsp[-2].attr_list)));
- if (!parse_only && do_typelib) current_typelib = (yyval.typelib);
- }
--#line 2931 "parser.tab.c" /* yacc.c:1648 */
-+#line 2926 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 56:
--#line 446 "parser.y" /* yacc.c:1648 */
-+#line 444 "parser.y" /* yacc.c:1646 */
- { (yyval.typelib) = (yyvsp[-3].typelib); (yyval.typelib)->stmts = (yyvsp[-2].stmt_list); }
--#line 2937 "parser.tab.c" /* yacc.c:1648 */
-+#line 2932 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 57:
--#line 449 "parser.y" /* yacc.c:1648 */
-+#line 447 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = NULL; }
--#line 2943 "parser.tab.c" /* yacc.c:1648 */
-+#line 2938 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 59:
--#line 453 "parser.y" /* yacc.c:1648 */
-+#line 451 "parser.y" /* yacc.c:1646 */
- { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); }
--#line 2949 "parser.tab.c" /* yacc.c:1648 */
-+#line 2944 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 60:
--#line 454 "parser.y" /* yacc.c:1648 */
-+#line 452 "parser.y" /* yacc.c:1646 */
- { check_arg_attrs((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) ); }
--#line 2955 "parser.tab.c" /* yacc.c:1648 */
-+#line 2950 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 62:
--#line 458 "parser.y" /* yacc.c:1648 */
-+#line 456 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = append_var( (yyvsp[-2].var_list), make_var(strdup("...")) ); }
--#line 2961 "parser.tab.c" /* yacc.c:1648 */
-+#line 2956 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 63:
--#line 462 "parser.y" /* yacc.c:1648 */
-+#line 460 "parser.y" /* yacc.c:1646 */
- { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
- error_loc("invalid storage class for function parameter\n");
- (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
- free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
- }
--#line 2971 "parser.tab.c" /* yacc.c:1648 */
-+#line 2966 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 64:
--#line 467 "parser.y" /* yacc.c:1648 */
-+#line 465 "parser.y" /* yacc.c:1646 */
- { if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
- error_loc("invalid storage class for function parameter\n");
- (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
- free((yyvsp[-1].declspec)); free((yyvsp[0].declarator));
- }
--#line 2981 "parser.tab.c" /* yacc.c:1648 */
-+#line 2976 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 65:
--#line 474 "parser.y" /* yacc.c:1648 */
-+#line 472 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = (yyvsp[-1].expr);
- if (!(yyval.expr)->is_const || (yyval.expr)->cval <= 0)
- error_loc("array dimension is not a positive integer constant\n");
- }
--#line 2990 "parser.tab.c" /* yacc.c:1648 */
-+#line 2985 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 66:
--#line 478 "parser.y" /* yacc.c:1648 */
-+#line 476 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr(EXPR_VOID); }
--#line 2996 "parser.tab.c" /* yacc.c:1648 */
-+#line 2991 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 67:
--#line 479 "parser.y" /* yacc.c:1648 */
-+#line 477 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr(EXPR_VOID); }
--#line 3002 "parser.tab.c" /* yacc.c:1648 */
-+#line 2997 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 68:
--#line 482 "parser.y" /* yacc.c:1648 */
-+#line 480 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = NULL; }
--#line 3008 "parser.tab.c" /* yacc.c:1648 */
-+#line 3003 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 70:
--#line 487 "parser.y" /* yacc.c:1648 */
-+#line 485 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = (yyvsp[-1].attr_list); }
--#line 3014 "parser.tab.c" /* yacc.c:1648 */
-+#line 3009 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 71:
--#line 490 "parser.y" /* yacc.c:1648 */
-+#line 488 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); }
--#line 3020 "parser.tab.c" /* yacc.c:1648 */
-+#line 3015 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 72:
--#line 491 "parser.y" /* yacc.c:1648 */
-+#line 489 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); }
--#line 3026 "parser.tab.c" /* yacc.c:1648 */
-+#line 3021 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 73:
--#line 492 "parser.y" /* yacc.c:1648 */
-+#line 490 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); }
--#line 3032 "parser.tab.c" /* yacc.c:1648 */
-+#line 3027 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 74:
--#line 495 "parser.y" /* yacc.c:1648 */
-+#line 493 "parser.y" /* yacc.c:1646 */
- { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); }
--#line 3038 "parser.tab.c" /* yacc.c:1648 */
-+#line 3033 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 75:
--#line 496 "parser.y" /* yacc.c:1648 */
-+#line 494 "parser.y" /* yacc.c:1646 */
- { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); }
--#line 3044 "parser.tab.c" /* yacc.c:1648 */
-+#line 3039 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 76:
--#line 499 "parser.y" /* yacc.c:1648 */
-+#line 497 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = NULL; }
--#line 3050 "parser.tab.c" /* yacc.c:1648 */
-+#line 3045 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 77:
--#line 500 "parser.y" /* yacc.c:1648 */
-+#line 498 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); }
--#line 3056 "parser.tab.c" /* yacc.c:1648 */
-+#line 3051 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 78:
--#line 501 "parser.y" /* yacc.c:1648 */
-+#line 499 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_ANNOTATION, (yyvsp[-1].str)); }
--#line 3062 "parser.tab.c" /* yacc.c:1648 */
-+#line 3057 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 79:
--#line 502 "parser.y" /* yacc.c:1648 */
-+#line 500 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_APPOBJECT); }
--#line 3068 "parser.tab.c" /* yacc.c:1648 */
-+#line 3063 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 80:
--#line 503 "parser.y" /* yacc.c:1648 */
-+#line 501 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_ASYNC); }
--#line 3074 "parser.tab.c" /* yacc.c:1648 */
-+#line 3069 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 81:
--#line 504 "parser.y" /* yacc.c:1648 */
-+#line 502 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); }
--#line 3080 "parser.tab.c" /* yacc.c:1648 */
-+#line 3075 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 82:
--#line 505 "parser.y" /* yacc.c:1648 */
-+#line 503 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_BINDABLE); }
--#line 3086 "parser.tab.c" /* yacc.c:1648 */
-+#line 3081 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 83:
--#line 506 "parser.y" /* yacc.c:1648 */
-+#line 504 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_BROADCAST); }
--#line 3092 "parser.tab.c" /* yacc.c:1648 */
-+#line 3087 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 84:
--#line 507 "parser.y" /* yacc.c:1648 */
-+#line 505 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); }
--#line 3098 "parser.tab.c" /* yacc.c:1648 */
-+#line 3093 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 85:
--#line 508 "parser.y" /* yacc.c:1648 */
-+#line 506 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); }
--#line 3104 "parser.tab.c" /* yacc.c:1648 */
-+#line 3099 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 86:
--#line 509 "parser.y" /* yacc.c:1648 */
-+#line 507 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_CODE); }
--#line 3110 "parser.tab.c" /* yacc.c:1648 */
-+#line 3105 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 87:
--#line 510 "parser.y" /* yacc.c:1648 */
-+#line 508 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_COMMSTATUS); }
--#line 3116 "parser.tab.c" /* yacc.c:1648 */
-+#line 3111 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 88:
--#line 511 "parser.y" /* yacc.c:1648 */
-+#line 509 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); }
--#line 3122 "parser.tab.c" /* yacc.c:1648 */
-+#line 3117 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 89:
--#line 512 "parser.y" /* yacc.c:1648 */
-+#line 510 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
--#line 3128 "parser.tab.c" /* yacc.c:1648 */
-+#line 3123 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 90:
--#line 513 "parser.y" /* yacc.c:1648 */
-+#line 511 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
--#line 3134 "parser.tab.c" /* yacc.c:1648 */
-+#line 3129 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 91:
--#line 514 "parser.y" /* yacc.c:1648 */
-+#line 512 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_CONTROL); }
--#line 3140 "parser.tab.c" /* yacc.c:1648 */
-+#line 3135 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 92:
--#line 515 "parser.y" /* yacc.c:1648 */
-+#line 513 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DECODE); }
--#line 3146 "parser.tab.c" /* yacc.c:1648 */
-+#line 3141 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 93:
--#line 516 "parser.y" /* yacc.c:1648 */
-+#line 514 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DEFAULT); }
--#line 3152 "parser.tab.c" /* yacc.c:1648 */
-+#line 3147 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 94:
--#line 517 "parser.y" /* yacc.c:1648 */
-+#line 515 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DEFAULTBIND); }
--#line 3158 "parser.tab.c" /* yacc.c:1648 */
-+#line 3153 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 95:
--#line 518 "parser.y" /* yacc.c:1648 */
-+#line 516 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); }
--#line 3164 "parser.tab.c" /* yacc.c:1648 */
-+#line 3159 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 96:
--#line 519 "parser.y" /* yacc.c:1648 */
-+#line 517 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE, (yyvsp[-1].expr)); }
--#line 3170 "parser.tab.c" /* yacc.c:1648 */
-+#line 3165 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 97:
--#line 520 "parser.y" /* yacc.c:1648 */
-+#line 518 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); }
--#line 3176 "parser.tab.c" /* yacc.c:1648 */
-+#line 3171 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 98:
--#line 521 "parser.y" /* yacc.c:1648 */
-+#line 519 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DISABLECONSISTENCYCHECK); }
--#line 3182 "parser.tab.c" /* yacc.c:1648 */
-+#line 3177 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 99:
--#line 522 "parser.y" /* yacc.c:1648 */
-+#line 520 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); }
--#line 3188 "parser.tab.c" /* yacc.c:1648 */
-+#line 3183 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 100:
--#line 523 "parser.y" /* yacc.c:1648 */
-+#line 521 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); }
--#line 3194 "parser.tab.c" /* yacc.c:1648 */
-+#line 3189 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 101:
--#line 524 "parser.y" /* yacc.c:1648 */
-+#line 522 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DUAL); }
--#line 3200 "parser.tab.c" /* yacc.c:1648 */
-+#line 3195 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 102:
--#line 525 "parser.y" /* yacc.c:1648 */
-+#line 523 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_ENABLEALLOCATE); }
--#line 3206 "parser.tab.c" /* yacc.c:1648 */
-+#line 3201 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 103:
--#line 526 "parser.y" /* yacc.c:1648 */
-+#line 524 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_ENCODE); }
--#line 3212 "parser.tab.c" /* yacc.c:1648 */
-+#line 3207 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 104:
--#line 527 "parser.y" /* yacc.c:1648 */
-+#line 525 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); }
--#line 3218 "parser.tab.c" /* yacc.c:1648 */
-+#line 3213 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 105:
--#line 528 "parser.y" /* yacc.c:1648 */
-+#line 526 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_ENTRY, (yyvsp[-1].expr)); }
--#line 3224 "parser.tab.c" /* yacc.c:1648 */
-+#line 3219 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 106:
--#line 529 "parser.y" /* yacc.c:1648 */
-+#line 527 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
--#line 3230 "parser.tab.c" /* yacc.c:1648 */
-+#line 3225 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 107:
--#line 530 "parser.y" /* yacc.c:1648 */
-+#line 528 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_FAULTSTATUS); }
--#line 3236 "parser.tab.c" /* yacc.c:1648 */
-+#line 3231 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 108:
--#line 531 "parser.y" /* yacc.c:1648 */
-+#line 529 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_FORCEALLOCATE); }
--#line 3242 "parser.tab.c" /* yacc.c:1648 */
-+#line 3237 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 109:
--#line 532 "parser.y" /* yacc.c:1648 */
-+#line 530 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_HANDLE); }
--#line 3248 "parser.tab.c" /* yacc.c:1648 */
-+#line 3243 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 110:
--#line 533 "parser.y" /* yacc.c:1648 */
-+#line 531 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); }
--#line 3254 "parser.tab.c" /* yacc.c:1648 */
-+#line 3249 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 111:
--#line 534 "parser.y" /* yacc.c:1648 */
-+#line 532 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); }
--#line 3260 "parser.tab.c" /* yacc.c:1648 */
-+#line 3255 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 112:
--#line 535 "parser.y" /* yacc.c:1648 */
-+#line 533 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); }
--#line 3266 "parser.tab.c" /* yacc.c:1648 */
-+#line 3261 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 113:
--#line 536 "parser.y" /* yacc.c:1648 */
-+#line 534 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); }
--#line 3272 "parser.tab.c" /* yacc.c:1648 */
-+#line 3267 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 114:
--#line 537 "parser.y" /* yacc.c:1648 */
-+#line 535 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); }
--#line 3278 "parser.tab.c" /* yacc.c:1648 */
-+#line 3273 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 115:
--#line 538 "parser.y" /* yacc.c:1648 */
-+#line 536 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_HIDDEN); }
--#line 3284 "parser.tab.c" /* yacc.c:1648 */
-+#line 3279 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 116:
--#line 539 "parser.y" /* yacc.c:1648 */
-+#line 537 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); }
--#line 3290 "parser.tab.c" /* yacc.c:1648 */
-+#line 3285 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 117:
--#line 540 "parser.y" /* yacc.c:1648 */
-+#line 538 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); }
--#line 3296 "parser.tab.c" /* yacc.c:1648 */
-+#line 3291 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 118:
--#line 541 "parser.y" /* yacc.c:1648 */
-+#line 539 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_IGNORE); }
--#line 3302 "parser.tab.c" /* yacc.c:1648 */
-+#line 3297 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 119:
--#line 542 "parser.y" /* yacc.c:1648 */
-+#line 540 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); }
--#line 3308 "parser.tab.c" /* yacc.c:1648 */
-+#line 3303 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 120:
--#line 543 "parser.y" /* yacc.c:1648 */
-+#line 541 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); }
--#line 3314 "parser.tab.c" /* yacc.c:1648 */
-+#line 3309 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 121:
--#line 544 "parser.y" /* yacc.c:1648 */
-+#line 542 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].var)); }
--#line 3320 "parser.tab.c" /* yacc.c:1648 */
-+#line 3315 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 122:
--#line 545 "parser.y" /* yacc.c:1648 */
-+#line 543 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_IN); }
--#line 3326 "parser.tab.c" /* yacc.c:1648 */
-+#line 3321 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 123:
--#line 546 "parser.y" /* yacc.c:1648 */
-+#line 544 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_INPUTSYNC); }
--#line 3332 "parser.tab.c" /* yacc.c:1648 */
-+#line 3327 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 124:
--#line 547 "parser.y" /* yacc.c:1648 */
-+#line 545 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); }
--#line 3338 "parser.tab.c" /* yacc.c:1648 */
-+#line 3333 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 125:
--#line 548 "parser.y" /* yacc.c:1648 */
-+#line 546 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_LIBLCID, (yyvsp[-1].expr)); }
--#line 3344 "parser.tab.c" /* yacc.c:1648 */
-+#line 3339 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 126:
--#line 549 "parser.y" /* yacc.c:1648 */
-+#line 547 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_PARAMLCID); }
--#line 3350 "parser.tab.c" /* yacc.c:1648 */
-+#line 3345 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 127:
--#line 550 "parser.y" /* yacc.c:1648 */
-+#line 548 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_LICENSED); }
--#line 3356 "parser.tab.c" /* yacc.c:1648 */
-+#line 3351 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 128:
--#line 551 "parser.y" /* yacc.c:1648 */
-+#line 549 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_LOCAL); }
--#line 3362 "parser.tab.c" /* yacc.c:1648 */
-+#line 3357 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 129:
--#line 552 "parser.y" /* yacc.c:1648 */
-+#line 550 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_MAYBE); }
--#line 3368 "parser.tab.c" /* yacc.c:1648 */
-+#line 3363 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 130:
--#line 553 "parser.y" /* yacc.c:1648 */
-+#line 551 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_MESSAGE); }
--#line 3374 "parser.tab.c" /* yacc.c:1648 */
-+#line 3369 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 131:
--#line 554 "parser.y" /* yacc.c:1648 */
-+#line 552 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_NOCODE); }
--#line 3380 "parser.tab.c" /* yacc.c:1648 */
-+#line 3375 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 132:
--#line 555 "parser.y" /* yacc.c:1648 */
-+#line 553 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); }
--#line 3386 "parser.tab.c" /* yacc.c:1648 */
-+#line 3381 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 133:
--#line 556 "parser.y" /* yacc.c:1648 */
-+#line 554 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_NONCREATABLE); }
--#line 3392 "parser.tab.c" /* yacc.c:1648 */
-+#line 3387 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 134:
--#line 557 "parser.y" /* yacc.c:1648 */
-+#line 555 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); }
--#line 3398 "parser.tab.c" /* yacc.c:1648 */
-+#line 3393 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 135:
--#line 558 "parser.y" /* yacc.c:1648 */
-+#line 556 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_NOTIFY); }
--#line 3404 "parser.tab.c" /* yacc.c:1648 */
-+#line 3399 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 136:
--#line 559 "parser.y" /* yacc.c:1648 */
-+#line 557 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_NOTIFYFLAG); }
--#line 3410 "parser.tab.c" /* yacc.c:1648 */
-+#line 3405 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 137:
--#line 560 "parser.y" /* yacc.c:1648 */
-+#line 558 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_OBJECT); }
--#line 3416 "parser.tab.c" /* yacc.c:1648 */
-+#line 3411 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 138:
--#line 561 "parser.y" /* yacc.c:1648 */
-+#line 559 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_ODL); }
--#line 3422 "parser.tab.c" /* yacc.c:1648 */
-+#line 3417 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 139:
--#line 562 "parser.y" /* yacc.c:1648 */
-+#line 560 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); }
--#line 3428 "parser.tab.c" /* yacc.c:1648 */
-+#line 3423 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 140:
--#line 563 "parser.y" /* yacc.c:1648 */
-+#line 561 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_OPTIMIZE, (yyvsp[-1].str)); }
--#line 3434 "parser.tab.c" /* yacc.c:1648 */
-+#line 3429 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 141:
--#line 564 "parser.y" /* yacc.c:1648 */
-+#line 562 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_OPTIONAL); }
--#line 3440 "parser.tab.c" /* yacc.c:1648 */
-+#line 3435 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 142:
--#line 565 "parser.y" /* yacc.c:1648 */
-+#line 563 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_OUT); }
--#line 3446 "parser.tab.c" /* yacc.c:1648 */
-+#line 3441 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 143:
--#line 566 "parser.y" /* yacc.c:1648 */
-+#line 564 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_PARTIALIGNORE); }
--#line 3452 "parser.tab.c" /* yacc.c:1648 */
-+#line 3447 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 144:
--#line 567 "parser.y" /* yacc.c:1648 */
-+#line 565 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); }
--#line 3458 "parser.tab.c" /* yacc.c:1648 */
-+#line 3453 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 145:
--#line 568 "parser.y" /* yacc.c:1648 */
-+#line 566 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_PROGID, (yyvsp[-1].str)); }
--#line 3464 "parser.tab.c" /* yacc.c:1648 */
-+#line 3459 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 146:
--#line 569 "parser.y" /* yacc.c:1648 */
-+#line 567 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_PROPGET); }
--#line 3470 "parser.tab.c" /* yacc.c:1648 */
-+#line 3465 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 147:
--#line 570 "parser.y" /* yacc.c:1648 */
-+#line 568 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_PROPPUT); }
--#line 3476 "parser.tab.c" /* yacc.c:1648 */
-+#line 3471 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 148:
--#line 571 "parser.y" /* yacc.c:1648 */
-+#line 569 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_PROPPUTREF); }
--#line 3482 "parser.tab.c" /* yacc.c:1648 */
-+#line 3477 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 149:
--#line 572 "parser.y" /* yacc.c:1648 */
-+#line 570 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_PROXY); }
--#line 3488 "parser.tab.c" /* yacc.c:1648 */
-+#line 3483 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 150:
--#line 573 "parser.y" /* yacc.c:1648 */
-+#line 571 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_PUBLIC); }
--#line 3494 "parser.tab.c" /* yacc.c:1648 */
-+#line 3489 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 151:
--#line 575 "parser.y" /* yacc.c:1648 */
-+#line 573 "parser.y" /* yacc.c:1646 */
- { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) );
- list = append_expr( list, (yyvsp[-1].expr) );
- (yyval.attr) = make_attrp(ATTR_RANGE, list); }
--#line 3502 "parser.tab.c" /* yacc.c:1648 */
-+#line 3497 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 152:
--#line 578 "parser.y" /* yacc.c:1648 */
-+#line 576 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_READONLY); }
--#line 3508 "parser.tab.c" /* yacc.c:1648 */
-+#line 3503 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 153:
--#line 579 "parser.y" /* yacc.c:1648 */
-+#line 577 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_REPRESENTAS, (yyvsp[-1].type)); }
--#line 3514 "parser.tab.c" /* yacc.c:1648 */
-+#line 3509 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 154:
--#line 580 "parser.y" /* yacc.c:1648 */
-+#line 578 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); }
--#line 3520 "parser.tab.c" /* yacc.c:1648 */
-+#line 3515 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 155:
--#line 581 "parser.y" /* yacc.c:1648 */
-+#line 579 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_RESTRICTED); }
--#line 3526 "parser.tab.c" /* yacc.c:1648 */
-+#line 3521 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 156:
--#line 582 "parser.y" /* yacc.c:1648 */
-+#line 580 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_RETVAL); }
--#line 3532 "parser.tab.c" /* yacc.c:1648 */
-+#line 3527 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 157:
--#line 583 "parser.y" /* yacc.c:1648 */
-+#line 581 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); }
--#line 3538 "parser.tab.c" /* yacc.c:1648 */
-+#line 3533 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 158:
--#line 584 "parser.y" /* yacc.c:1648 */
-+#line 582 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_SOURCE); }
--#line 3544 "parser.tab.c" /* yacc.c:1648 */
-+#line 3539 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 159:
--#line 585 "parser.y" /* yacc.c:1648 */
-+#line 583 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); }
--#line 3550 "parser.tab.c" /* yacc.c:1648 */
-+#line 3545 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 160:
--#line 586 "parser.y" /* yacc.c:1648 */
-+#line 584 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_STRING); }
--#line 3556 "parser.tab.c" /* yacc.c:1648 */
-+#line 3551 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 161:
--#line 587 "parser.y" /* yacc.c:1648 */
-+#line 585 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); }
--#line 3562 "parser.tab.c" /* yacc.c:1648 */
-+#line 3557 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 162:
--#line 588 "parser.y" /* yacc.c:1648 */
-+#line 586 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); }
--#line 3568 "parser.tab.c" /* yacc.c:1648 */
-+#line 3563 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 163:
--#line 589 "parser.y" /* yacc.c:1648 */
-+#line 587 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); }
--#line 3574 "parser.tab.c" /* yacc.c:1648 */
-+#line 3569 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 164:
--#line 590 "parser.y" /* yacc.c:1648 */
-+#line 588 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrv(ATTR_THREADING, (yyvsp[-1].num)); }
--#line 3580 "parser.tab.c" /* yacc.c:1648 */
-+#line 3575 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 165:
--#line 591 "parser.y" /* yacc.c:1648 */
-+#line 589 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_UIDEFAULT); }
--#line 3586 "parser.tab.c" /* yacc.c:1648 */
-+#line 3581 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 166:
--#line 592 "parser.y" /* yacc.c:1648 */
-+#line 590 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_USESGETLASTERROR); }
--#line 3592 "parser.tab.c" /* yacc.c:1648 */
-+#line 3587 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 167:
--#line 593 "parser.y" /* yacc.c:1648 */
-+#line 591 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_USERMARSHAL, (yyvsp[-1].type)); }
--#line 3598 "parser.tab.c" /* yacc.c:1648 */
-+#line 3593 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 168:
--#line 594 "parser.y" /* yacc.c:1648 */
-+#line 592 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); }
--#line 3604 "parser.tab.c" /* yacc.c:1648 */
-+#line 3599 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 169:
--#line 595 "parser.y" /* yacc.c:1648 */
-+#line 593 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_ASYNCUUID, (yyvsp[-1].uuid)); }
--#line 3610 "parser.tab.c" /* yacc.c:1648 */
-+#line 3605 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 170:
--#line 596 "parser.y" /* yacc.c:1648 */
-+#line 594 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_V1ENUM); }
--#line 3616 "parser.tab.c" /* yacc.c:1648 */
-+#line 3611 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 171:
--#line 597 "parser.y" /* yacc.c:1648 */
-+#line 595 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_VARARG); }
--#line 3622 "parser.tab.c" /* yacc.c:1648 */
-+#line 3617 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 172:
--#line 598 "parser.y" /* yacc.c:1648 */
-+#line 596 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); }
--#line 3628 "parser.tab.c" /* yacc.c:1648 */
-+#line 3623 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 173:
--#line 599 "parser.y" /* yacc.c:1648 */
-+#line 597 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_VIPROGID, (yyvsp[-1].str)); }
--#line 3634 "parser.tab.c" /* yacc.c:1648 */
-+#line 3629 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 174:
--#line 600 "parser.y" /* yacc.c:1648 */
-+#line 598 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); }
--#line 3640 "parser.tab.c" /* yacc.c:1648 */
-+#line 3635 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 175:
--#line 601 "parser.y" /* yacc.c:1648 */
-+#line 599 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); }
--#line 3646 "parser.tab.c" /* yacc.c:1648 */
-+#line 3641 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 177:
--#line 606 "parser.y" /* yacc.c:1648 */
-+#line 604 "parser.y" /* yacc.c:1646 */
- { if (!is_valid_uuid((yyvsp[0].str)))
- error_loc("invalid UUID: %s\n", (yyvsp[0].str));
- (yyval.uuid) = parse_uuid((yyvsp[0].str)); }
--#line 3654 "parser.tab.c" /* yacc.c:1648 */
-+#line 3649 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 178:
--#line 611 "parser.y" /* yacc.c:1648 */
-+#line 609 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = xstrdup("__cdecl"); }
--#line 3660 "parser.tab.c" /* yacc.c:1648 */
-+#line 3655 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 179:
--#line 612 "parser.y" /* yacc.c:1648 */
-+#line 610 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = xstrdup("__fastcall"); }
--#line 3666 "parser.tab.c" /* yacc.c:1648 */
-+#line 3661 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 180:
--#line 613 "parser.y" /* yacc.c:1648 */
-+#line 611 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = xstrdup("__pascal"); }
--#line 3672 "parser.tab.c" /* yacc.c:1648 */
-+#line 3667 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 181:
--#line 614 "parser.y" /* yacc.c:1648 */
-+#line 612 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = xstrdup("__stdcall"); }
--#line 3678 "parser.tab.c" /* yacc.c:1648 */
-+#line 3673 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 182:
--#line 617 "parser.y" /* yacc.c:1648 */
-+#line 615 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = NULL; }
--#line 3684 "parser.tab.c" /* yacc.c:1648 */
-+#line 3679 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 183:
--#line 618 "parser.y" /* yacc.c:1648 */
-+#line 616 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
--#line 3690 "parser.tab.c" /* yacc.c:1648 */
-+#line 3685 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 184:
--#line 621 "parser.y" /* yacc.c:1648 */
-+#line 619 "parser.y" /* yacc.c:1646 */
- { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) ));
- (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
- (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
- }
--#line 3699 "parser.tab.c" /* yacc.c:1648 */
-+#line 3694 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 185:
--#line 625 "parser.y" /* yacc.c:1648 */
-+#line 623 "parser.y" /* yacc.c:1646 */
- { attr_t *a = make_attr(ATTR_DEFAULT);
- (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
- (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
- }
--#line 3708 "parser.tab.c" /* yacc.c:1648 */
-+#line 3703 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 186:
--#line 631 "parser.y" /* yacc.c:1648 */
-+#line 629 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = NULL; }
--#line 3714 "parser.tab.c" /* yacc.c:1648 */
-+#line 3709 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 187:
--#line 632 "parser.y" /* yacc.c:1648 */
-+#line 630 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = (yyvsp[-1].var_list); }
--#line 3720 "parser.tab.c" /* yacc.c:1648 */
-+#line 3715 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 189:
--#line 636 "parser.y" /* yacc.c:1648 */
-+#line 634 "parser.y" /* yacc.c:1646 */
- { if (!(yyvsp[0].var)->eval)
- (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
- (yyval.var_list) = append_var( NULL, (yyvsp[0].var) );
- }
--#line 3729 "parser.tab.c" /* yacc.c:1648 */
-+#line 3724 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 190:
--#line 640 "parser.y" /* yacc.c:1648 */
-+#line 638 "parser.y" /* yacc.c:1646 */
- { if (!(yyvsp[0].var)->eval)
- {
- var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry );
-@@ -3740,656 +3735,656 @@ yyreduce:
- }
- (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var) );
- }
--#line 3744 "parser.tab.c" /* yacc.c:1648 */
-+#line 3739 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 191:
--#line 652 "parser.y" /* yacc.c:1648 */
-+#line 650 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = reg_const((yyvsp[-2].var));
- (yyval.var)->eval = (yyvsp[0].expr);
-- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
-+ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
- }
--#line 3753 "parser.tab.c" /* yacc.c:1648 */
-+#line 3748 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 192:
--#line 656 "parser.y" /* yacc.c:1648 */
-+#line 654 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = reg_const((yyvsp[0].var));
-- (yyval.var)->type = type_new_int(TYPE_BASIC_INT, 0);
-+ (yyval.var)->declspec.type = type_new_int(TYPE_BASIC_INT, 0);
- }
--#line 3761 "parser.tab.c" /* yacc.c:1648 */
-+#line 3756 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 193:
--#line 661 "parser.y" /* yacc.c:1648 */
-+#line 659 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_enum((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
--#line 3767 "parser.tab.c" /* yacc.c:1648 */
-+#line 3762 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 194:
--#line 664 "parser.y" /* yacc.c:1648 */
-+#line 662 "parser.y" /* yacc.c:1646 */
- { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
--#line 3773 "parser.tab.c" /* yacc.c:1648 */
-+#line 3768 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 195:
--#line 665 "parser.y" /* yacc.c:1648 */
-+#line 663 "parser.y" /* yacc.c:1646 */
- { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
--#line 3779 "parser.tab.c" /* yacc.c:1648 */
-+#line 3774 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 196:
--#line 668 "parser.y" /* yacc.c:1648 */
-+#line 666 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr(EXPR_VOID); }
--#line 3785 "parser.tab.c" /* yacc.c:1648 */
-+#line 3780 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 198:
--#line 672 "parser.y" /* yacc.c:1648 */
-+#line 670 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); }
--#line 3791 "parser.tab.c" /* yacc.c:1648 */
-+#line 3786 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 199:
--#line 673 "parser.y" /* yacc.c:1648 */
-+#line 671 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); }
--#line 3797 "parser.tab.c" /* yacc.c:1648 */
-+#line 3792 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 200:
--#line 674 "parser.y" /* yacc.c:1648 */
-+#line 672 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); }
--#line 3803 "parser.tab.c" /* yacc.c:1648 */
-+#line 3798 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 201:
--#line 675 "parser.y" /* yacc.c:1648 */
-+#line 673 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); }
--#line 3809 "parser.tab.c" /* yacc.c:1648 */
-+#line 3804 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 202:
--#line 676 "parser.y" /* yacc.c:1648 */
-+#line 674 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprl(EXPR_NUM, 0); }
--#line 3815 "parser.tab.c" /* yacc.c:1648 */
-+#line 3810 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 203:
--#line 677 "parser.y" /* yacc.c:1648 */
-+#line 675 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); }
--#line 3821 "parser.tab.c" /* yacc.c:1648 */
-+#line 3816 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 204:
--#line 678 "parser.y" /* yacc.c:1648 */
-+#line 676 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprs(EXPR_STRLIT, (yyvsp[0].str)); }
--#line 3827 "parser.tab.c" /* yacc.c:1648 */
-+#line 3822 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 205:
--#line 679 "parser.y" /* yacc.c:1648 */
-+#line 677 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprs(EXPR_WSTRLIT, (yyvsp[0].str)); }
--#line 3833 "parser.tab.c" /* yacc.c:1648 */
-+#line 3828 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 206:
--#line 680 "parser.y" /* yacc.c:1648 */
-+#line 678 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprs(EXPR_CHARCONST, (yyvsp[0].str)); }
--#line 3839 "parser.tab.c" /* yacc.c:1648 */
-+#line 3834 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 207:
--#line 681 "parser.y" /* yacc.c:1648 */
-+#line 679 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); }
--#line 3845 "parser.tab.c" /* yacc.c:1648 */
-+#line 3840 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 208:
--#line 682 "parser.y" /* yacc.c:1648 */
-+#line 680 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3851 "parser.tab.c" /* yacc.c:1648 */
-+#line 3846 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 209:
--#line 683 "parser.y" /* yacc.c:1648 */
-+#line 681 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_LOGOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3857 "parser.tab.c" /* yacc.c:1648 */
-+#line 3852 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 210:
--#line 684 "parser.y" /* yacc.c:1648 */
-+#line 682 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_LOGAND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3863 "parser.tab.c" /* yacc.c:1648 */
-+#line 3858 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 211:
--#line 685 "parser.y" /* yacc.c:1648 */
-+#line 683 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3869 "parser.tab.c" /* yacc.c:1648 */
-+#line 3864 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 212:
--#line 686 "parser.y" /* yacc.c:1648 */
-+#line 684 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_XOR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3875 "parser.tab.c" /* yacc.c:1648 */
-+#line 3870 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 213:
--#line 687 "parser.y" /* yacc.c:1648 */
-+#line 685 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3881 "parser.tab.c" /* yacc.c:1648 */
-+#line 3876 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 214:
--#line 688 "parser.y" /* yacc.c:1648 */
-+#line 686 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_EQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3887 "parser.tab.c" /* yacc.c:1648 */
-+#line 3882 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 215:
--#line 689 "parser.y" /* yacc.c:1648 */
-+#line 687 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_INEQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3893 "parser.tab.c" /* yacc.c:1648 */
-+#line 3888 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 216:
--#line 690 "parser.y" /* yacc.c:1648 */
-+#line 688 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_GTR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3899 "parser.tab.c" /* yacc.c:1648 */
-+#line 3894 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 217:
--#line 691 "parser.y" /* yacc.c:1648 */
-+#line 689 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_LESS, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3905 "parser.tab.c" /* yacc.c:1648 */
-+#line 3900 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 218:
--#line 692 "parser.y" /* yacc.c:1648 */
-+#line 690 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_GTREQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3911 "parser.tab.c" /* yacc.c:1648 */
-+#line 3906 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 219:
--#line 693 "parser.y" /* yacc.c:1648 */
-+#line 691 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_LESSEQL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3917 "parser.tab.c" /* yacc.c:1648 */
-+#line 3912 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 220:
--#line 694 "parser.y" /* yacc.c:1648 */
-+#line 692 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3923 "parser.tab.c" /* yacc.c:1648 */
-+#line 3918 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 221:
--#line 695 "parser.y" /* yacc.c:1648 */
-+#line 693 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3929 "parser.tab.c" /* yacc.c:1648 */
-+#line 3924 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 222:
--#line 696 "parser.y" /* yacc.c:1648 */
-+#line 694 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3935 "parser.tab.c" /* yacc.c:1648 */
-+#line 3930 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 223:
--#line 697 "parser.y" /* yacc.c:1648 */
-+#line 695 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3941 "parser.tab.c" /* yacc.c:1648 */
-+#line 3936 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 224:
--#line 698 "parser.y" /* yacc.c:1648 */
-+#line 696 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_MOD, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3947 "parser.tab.c" /* yacc.c:1648 */
-+#line 3942 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 225:
--#line 699 "parser.y" /* yacc.c:1648 */
-+#line 697 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3953 "parser.tab.c" /* yacc.c:1648 */
-+#line 3948 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 226:
--#line 700 "parser.y" /* yacc.c:1648 */
-+#line 698 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); }
--#line 3959 "parser.tab.c" /* yacc.c:1648 */
-+#line 3954 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 227:
--#line 701 "parser.y" /* yacc.c:1648 */
-+#line 699 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr1(EXPR_LOGNOT, (yyvsp[0].expr)); }
--#line 3965 "parser.tab.c" /* yacc.c:1648 */
-+#line 3960 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 228:
--#line 702 "parser.y" /* yacc.c:1648 */
-+#line 700 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); }
--#line 3971 "parser.tab.c" /* yacc.c:1648 */
-+#line 3966 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 229:
--#line 703 "parser.y" /* yacc.c:1648 */
-+#line 701 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr1(EXPR_POS, (yyvsp[0].expr)); }
--#line 3977 "parser.tab.c" /* yacc.c:1648 */
-+#line 3972 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 230:
--#line 704 "parser.y" /* yacc.c:1648 */
-+#line 702 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); }
--#line 3983 "parser.tab.c" /* yacc.c:1648 */
-+#line 3978 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 231:
--#line 705 "parser.y" /* yacc.c:1648 */
-+#line 703 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); }
--#line 3989 "parser.tab.c" /* yacc.c:1648 */
-+#line 3984 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 232:
--#line 706 "parser.y" /* yacc.c:1648 */
-+#line 704 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); }
--#line 3995 "parser.tab.c" /* yacc.c:1648 */
-+#line 3990 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 233:
--#line 707 "parser.y" /* yacc.c:1648 */
-+#line 705 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, (yyvsp[-2].expr)), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
--#line 4001 "parser.tab.c" /* yacc.c:1648 */
-+#line 3996 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 234:
--#line 708 "parser.y" /* yacc.c:1648 */
-+#line 706 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_MEMBER, (yyvsp[-2].expr), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); }
--#line 4007 "parser.tab.c" /* yacc.c:1648 */
-+#line 4002 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 235:
--#line 710 "parser.y" /* yacc.c:1648 */
-+#line 708 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprt(EXPR_CAST, declare_var(NULL, (yyvsp[-3].declspec), (yyvsp[-2].declarator), 0), (yyvsp[0].expr)); free((yyvsp[-3].declspec)); free((yyvsp[-2].declarator)); }
--#line 4013 "parser.tab.c" /* yacc.c:1648 */
-+#line 4008 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 236:
--#line 712 "parser.y" /* yacc.c:1648 */
-+#line 710 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_exprt(EXPR_SIZEOF, declare_var(NULL, (yyvsp[-2].declspec), (yyvsp[-1].declarator), 0), NULL); free((yyvsp[-2].declspec)); free((yyvsp[-1].declarator)); }
--#line 4019 "parser.tab.c" /* yacc.c:1648 */
-+#line 4014 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 237:
--#line 713 "parser.y" /* yacc.c:1648 */
-+#line 711 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = make_expr2(EXPR_ARRAY, (yyvsp[-3].expr), (yyvsp[-1].expr)); }
--#line 4025 "parser.tab.c" /* yacc.c:1648 */
-+#line 4020 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 238:
--#line 714 "parser.y" /* yacc.c:1648 */
-+#line 712 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = (yyvsp[-1].expr); }
--#line 4031 "parser.tab.c" /* yacc.c:1648 */
-+#line 4026 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 239:
--#line 717 "parser.y" /* yacc.c:1648 */
-+#line 715 "parser.y" /* yacc.c:1646 */
- { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); }
--#line 4037 "parser.tab.c" /* yacc.c:1648 */
-+#line 4032 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 240:
--#line 718 "parser.y" /* yacc.c:1648 */
-+#line 716 "parser.y" /* yacc.c:1646 */
- { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); }
--#line 4043 "parser.tab.c" /* yacc.c:1648 */
-+#line 4038 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 241:
--#line 721 "parser.y" /* yacc.c:1648 */
-+#line 719 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = (yyvsp[0].expr);
- if (!(yyval.expr)->is_const)
- error_loc("expression is not an integer constant\n");
- }
--#line 4052 "parser.tab.c" /* yacc.c:1648 */
-+#line 4047 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 242:
--#line 727 "parser.y" /* yacc.c:1648 */
-+#line 725 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = (yyvsp[0].expr);
- if (!(yyval.expr)->is_const && (yyval.expr)->type != EXPR_STRLIT && (yyval.expr)->type != EXPR_WSTRLIT)
- error_loc("expression is not constant\n");
- }
--#line 4061 "parser.tab.c" /* yacc.c:1648 */
-+#line 4056 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 243:
--#line 733 "parser.y" /* yacc.c:1648 */
-+#line 731 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = NULL; }
--#line 4067 "parser.tab.c" /* yacc.c:1648 */
-+#line 4062 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 244:
--#line 734 "parser.y" /* yacc.c:1648 */
-+#line 732 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = append_var_list((yyvsp[-1].var_list), (yyvsp[0].var_list)); }
--#line 4073 "parser.tab.c" /* yacc.c:1648 */
-+#line 4068 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 245:
--#line 738 "parser.y" /* yacc.c:1648 */
-+#line 736 "parser.y" /* yacc.c:1646 */
- { const char *first = LIST_ENTRY(list_head((yyvsp[-1].declarator_list)), declarator_t, entry)->var->name;
- check_field_attrs(first, (yyvsp[-3].attr_list));
- (yyval.var_list) = set_var_types((yyvsp[-3].attr_list), (yyvsp[-2].declspec), (yyvsp[-1].declarator_list));
- }
--#line 4082 "parser.tab.c" /* yacc.c:1648 */
-+#line 4077 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 246:
--#line 742 "parser.y" /* yacc.c:1648 */
-+#line 740 "parser.y" /* yacc.c:1646 */
- { var_t *v = make_var(NULL);
-- v->type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
-+ v->declspec.type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
- (yyval.var_list) = append_var(NULL, v);
- }
--#line 4091 "parser.tab.c" /* yacc.c:1648 */
-+#line 4086 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 247:
--#line 749 "parser.y" /* yacc.c:1648 */
-+#line 747 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = (yyvsp[-1].var); }
--#line 4097 "parser.tab.c" /* yacc.c:1648 */
-+#line 4092 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 248:
--#line 750 "parser.y" /* yacc.c:1648 */
-+#line 748 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); }
--#line 4103 "parser.tab.c" /* yacc.c:1648 */
-+#line 4098 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 249:
--#line 753 "parser.y" /* yacc.c:1648 */
-+#line 751 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = NULL; }
--#line 4109 "parser.tab.c" /* yacc.c:1648 */
-+#line 4104 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 250:
--#line 754 "parser.y" /* yacc.c:1648 */
-+#line 752 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); }
--#line 4115 "parser.tab.c" /* yacc.c:1648 */
-+#line 4110 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 251:
--#line 758 "parser.y" /* yacc.c:1648 */
-+#line 756 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = (yyvsp[-1].var); }
--#line 4121 "parser.tab.c" /* yacc.c:1648 */
-+#line 4116 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 252:
--#line 759 "parser.y" /* yacc.c:1648 */
-+#line 757 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = NULL; }
--#line 4127 "parser.tab.c" /* yacc.c:1648 */
-+#line 4122 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 253:
--#line 762 "parser.y" /* yacc.c:1648 */
-+#line 760 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = declare_var(check_field_attrs((yyvsp[0].declarator)->var->name, (yyvsp[-2].attr_list)),
- (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
- free((yyvsp[0].declarator));
- }
--#line 4136 "parser.tab.c" /* yacc.c:1648 */
-+#line 4131 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 254:
--#line 766 "parser.y" /* yacc.c:1648 */
-+#line 764 "parser.y" /* yacc.c:1646 */
- { var_t *v = make_var(NULL);
-- v->type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
-+ v->declspec.type = (yyvsp[0].type); v->attrs = (yyvsp[-1].attr_list);
- (yyval.var) = v;
- }
--#line 4145 "parser.tab.c" /* yacc.c:1648 */
-+#line 4140 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 255:
--#line 772 "parser.y" /* yacc.c:1648 */
-+#line 770 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = (yyvsp[0].var);
-- if (type_get_type((yyval.var)->type) != TYPE_FUNCTION)
-+ if (type_get_type((yyval.var)->declspec.type) != TYPE_FUNCTION)
- error_loc("only methods may be declared inside the methods section of a dispinterface\n");
- check_function_attrs((yyval.var)->name, (yyval.var)->attrs);
- }
--#line 4155 "parser.tab.c" /* yacc.c:1648 */
-+#line 4150 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 256:
--#line 781 "parser.y" /* yacc.c:1648 */
-+#line 779 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = declare_var((yyvsp[-2].attr_list), (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
- free((yyvsp[0].declarator));
- }
--#line 4163 "parser.tab.c" /* yacc.c:1648 */
-+#line 4158 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 257:
--#line 784 "parser.y" /* yacc.c:1648 */
-+#line 782 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = declare_var(NULL, (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
- free((yyvsp[0].declarator));
- }
--#line 4171 "parser.tab.c" /* yacc.c:1648 */
-+#line 4166 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 258:
--#line 789 "parser.y" /* yacc.c:1648 */
-+#line 787 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = NULL; }
--#line 4177 "parser.tab.c" /* yacc.c:1648 */
-+#line 4172 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 260:
--#line 793 "parser.y" /* yacc.c:1648 */
-+#line 791 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = NULL; }
--#line 4183 "parser.tab.c" /* yacc.c:1648 */
-+#line 4178 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 261:
--#line 794 "parser.y" /* yacc.c:1648 */
-+#line 792 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[0].str); }
--#line 4189 "parser.tab.c" /* yacc.c:1648 */
-+#line 4184 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 262:
--#line 795 "parser.y" /* yacc.c:1648 */
-+#line 793 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[0].str); }
--#line 4195 "parser.tab.c" /* yacc.c:1648 */
-+#line 4190 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 263:
--#line 798 "parser.y" /* yacc.c:1648 */
-+#line 796 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = make_var((yyvsp[0].str)); }
--#line 4201 "parser.tab.c" /* yacc.c:1648 */
-+#line 4196 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 264:
--#line 800 "parser.y" /* yacc.c:1648 */
-+#line 798 "parser.y" /* yacc.c:1646 */
- { (yyval.var) = make_var((yyvsp[0].str)); }
--#line 4207 "parser.tab.c" /* yacc.c:1648 */
-+#line 4202 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 265:
--#line 803 "parser.y" /* yacc.c:1648 */
-+#line 801 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4213 "parser.tab.c" /* yacc.c:1648 */
-+#line 4208 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 266:
--#line 804 "parser.y" /* yacc.c:1648 */
-+#line 802 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4219 "parser.tab.c" /* yacc.c:1648 */
-+#line 4214 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 268:
--#line 806 "parser.y" /* yacc.c:1648 */
-+#line 804 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), -1); }
--#line 4225 "parser.tab.c" /* yacc.c:1648 */
-+#line 4220 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 269:
--#line 807 "parser.y" /* yacc.c:1648 */
-+#line 805 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(type_basic_get_type((yyvsp[0].type)), 1); }
--#line 4231 "parser.tab.c" /* yacc.c:1648 */
-+#line 4226 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 270:
--#line 808 "parser.y" /* yacc.c:1648 */
-+#line 806 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_INT, 1); }
--#line 4237 "parser.tab.c" /* yacc.c:1648 */
-+#line 4232 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 271:
--#line 809 "parser.y" /* yacc.c:1648 */
-+#line 807 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4243 "parser.tab.c" /* yacc.c:1648 */
-+#line 4238 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 272:
--#line 810 "parser.y" /* yacc.c:1648 */
-+#line 808 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4249 "parser.tab.c" /* yacc.c:1648 */
-+#line 4244 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 273:
--#line 811 "parser.y" /* yacc.c:1648 */
-+#line 809 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4255 "parser.tab.c" /* yacc.c:1648 */
-+#line 4250 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 274:
--#line 812 "parser.y" /* yacc.c:1648 */
-+#line 810 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4261 "parser.tab.c" /* yacc.c:1648 */
-+#line 4256 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 275:
--#line 813 "parser.y" /* yacc.c:1648 */
-+#line 811 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4267 "parser.tab.c" /* yacc.c:1648 */
-+#line 4262 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 278:
--#line 820 "parser.y" /* yacc.c:1648 */
-+#line 818 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_INT, 0); }
--#line 4273 "parser.tab.c" /* yacc.c:1648 */
-+#line 4268 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 279:
--#line 821 "parser.y" /* yacc.c:1648 */
-+#line 819 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_INT16, 0); }
--#line 4279 "parser.tab.c" /* yacc.c:1648 */
-+#line 4274 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 280:
--#line 822 "parser.y" /* yacc.c:1648 */
-+#line 820 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_INT8, 0); }
--#line 4285 "parser.tab.c" /* yacc.c:1648 */
-+#line 4280 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 281:
--#line 823 "parser.y" /* yacc.c:1648 */
-+#line 821 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_LONG, 0); }
--#line 4291 "parser.tab.c" /* yacc.c:1648 */
-+#line 4286 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 282:
--#line 824 "parser.y" /* yacc.c:1648 */
-+#line 822 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_HYPER, 0); }
--#line 4297 "parser.tab.c" /* yacc.c:1648 */
-+#line 4292 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 283:
--#line 825 "parser.y" /* yacc.c:1648 */
-+#line 823 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_INT64, 0); }
--#line 4303 "parser.tab.c" /* yacc.c:1648 */
-+#line 4298 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 284:
--#line 826 "parser.y" /* yacc.c:1648 */
-+#line 824 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_CHAR, 0); }
--#line 4309 "parser.tab.c" /* yacc.c:1648 */
-+#line 4304 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 285:
--#line 827 "parser.y" /* yacc.c:1648 */
-+#line 825 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_INT32, 0); }
--#line 4315 "parser.tab.c" /* yacc.c:1648 */
-+#line 4310 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 286:
--#line 828 "parser.y" /* yacc.c:1648 */
-+#line 826 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_int(TYPE_BASIC_INT3264, 0); }
--#line 4321 "parser.tab.c" /* yacc.c:1648 */
-+#line 4316 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 287:
--#line 831 "parser.y" /* yacc.c:1648 */
-+#line 829 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_coclass((yyvsp[0].str)); }
--#line 4327 "parser.tab.c" /* yacc.c:1648 */
-+#line 4322 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 288:
--#line 832 "parser.y" /* yacc.c:1648 */
-+#line 830 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type((yyvsp[0].str), NULL, 0);
- if (type_get_type_detect_alias((yyval.type)) != TYPE_COCLASS)
- error_loc("%s was not declared a coclass at %s:%d\n",
- (yyvsp[0].str), (yyval.type)->loc_info.input_name,
- (yyval.type)->loc_info.line_number);
- }
--#line 4338 "parser.tab.c" /* yacc.c:1648 */
-+#line 4333 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 289:
--#line 840 "parser.y" /* yacc.c:1648 */
-+#line 838 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type);
- check_def((yyval.type));
- (yyval.type)->attrs = check_coclass_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
- }
--#line 4347 "parser.tab.c" /* yacc.c:1648 */
-+#line 4342 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 290:
--#line 847 "parser.y" /* yacc.c:1648 */
-+#line 845 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_coclass_define((yyvsp[-4].type), (yyvsp[-2].ifref_list)); }
--#line 4353 "parser.tab.c" /* yacc.c:1648 */
-+#line 4348 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 291:
--#line 850 "parser.y" /* yacc.c:1648 */
-+#line 848 "parser.y" /* yacc.c:1646 */
- { (yyval.str) = (yyvsp[0].str); }
--#line 4359 "parser.tab.c" /* yacc.c:1648 */
-+#line 4354 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 292:
--#line 853 "parser.y" /* yacc.c:1648 */
-+#line 851 "parser.y" /* yacc.c:1646 */
- { (yyval.ifref_list) = NULL; }
--#line 4365 "parser.tab.c" /* yacc.c:1648 */
-+#line 4360 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 293:
--#line 854 "parser.y" /* yacc.c:1648 */
-+#line 852 "parser.y" /* yacc.c:1646 */
- { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); }
--#line 4371 "parser.tab.c" /* yacc.c:1648 */
-+#line 4366 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 294:
--#line 858 "parser.y" /* yacc.c:1648 */
-+#line 856 "parser.y" /* yacc.c:1646 */
- { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); }
--#line 4377 "parser.tab.c" /* yacc.c:1648 */
-+#line 4372 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 295:
--#line 861 "parser.y" /* yacc.c:1648 */
-+#line 859 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
--#line 4383 "parser.tab.c" /* yacc.c:1648 */
-+#line 4378 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 296:
--#line 862 "parser.y" /* yacc.c:1648 */
-+#line 860 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
--#line 4389 "parser.tab.c" /* yacc.c:1648 */
-+#line 4384 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 297:
--#line 865 "parser.y" /* yacc.c:1648 */
-+#line 863 "parser.y" /* yacc.c:1646 */
- { attr_t *attrs;
- (yyval.type) = (yyvsp[0].type);
- check_def((yyval.type));
-@@ -4397,75 +4392,75 @@ yyreduce:
- (yyval.type)->attrs = append_attr( check_dispiface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list)), attrs );
- (yyval.type)->defined = TRUE;
- }
--#line 4401 "parser.tab.c" /* yacc.c:1648 */
-+#line 4396 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 298:
--#line 874 "parser.y" /* yacc.c:1648 */
-+#line 872 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = NULL; }
--#line 4407 "parser.tab.c" /* yacc.c:1648 */
-+#line 4402 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 299:
--#line 875 "parser.y" /* yacc.c:1648 */
-+#line 873 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
--#line 4413 "parser.tab.c" /* yacc.c:1648 */
-+#line 4408 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 300:
--#line 878 "parser.y" /* yacc.c:1648 */
-+#line 876 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = NULL; }
--#line 4419 "parser.tab.c" /* yacc.c:1648 */
-+#line 4414 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 301:
--#line 879 "parser.y" /* yacc.c:1648 */
-+#line 877 "parser.y" /* yacc.c:1646 */
- { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); }
--#line 4425 "parser.tab.c" /* yacc.c:1648 */
-+#line 4420 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 302:
--#line 885 "parser.y" /* yacc.c:1648 */
-+#line 883 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-4].type);
- type_dispinterface_define((yyval.type), (yyvsp[-2].var_list), (yyvsp[-1].var_list));
- }
--#line 4433 "parser.tab.c" /* yacc.c:1648 */
-+#line 4428 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 303:
--#line 889 "parser.y" /* yacc.c:1648 */
-+#line 887 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-4].type);
- type_dispinterface_define_from_iface((yyval.type), (yyvsp[-2].type));
- }
--#line 4441 "parser.tab.c" /* yacc.c:1648 */
-+#line 4436 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 304:
--#line 894 "parser.y" /* yacc.c:1648 */
-+#line 892 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = NULL; }
--#line 4447 "parser.tab.c" /* yacc.c:1648 */
-+#line 4442 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 305:
--#line 895 "parser.y" /* yacc.c:1648 */
-+#line 893 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error2((yyvsp[0].str), 0); }
--#line 4453 "parser.tab.c" /* yacc.c:1648 */
-+#line 4448 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 306:
--#line 898 "parser.y" /* yacc.c:1648 */
-+#line 896 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
--#line 4459 "parser.tab.c" /* yacc.c:1648 */
-+#line 4454 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 307:
--#line 899 "parser.y" /* yacc.c:1648 */
-+#line 897 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = get_type(TYPE_INTERFACE, (yyvsp[0].str), current_namespace, 0); }
--#line 4465 "parser.tab.c" /* yacc.c:1648 */
-+#line 4460 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 308:
--#line 902 "parser.y" /* yacc.c:1648 */
-+#line 900 "parser.y" /* yacc.c:1646 */
- { (yyval.ifinfo).interface = (yyvsp[0].type);
- (yyval.ifinfo).old_pointer_default = pointer_default;
- if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT))
-@@ -4474,11 +4469,11 @@ yyreduce:
- (yyvsp[0].type)->attrs = check_iface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
- (yyvsp[0].type)->defined = TRUE;
- }
--#line 4478 "parser.tab.c" /* yacc.c:1648 */
-+#line 4473 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 309:
--#line 913 "parser.y" /* yacc.c:1648 */
-+#line 911 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-5].ifinfo).interface;
- if((yyval.type) == (yyvsp[-4].type))
- error_loc("Interface can't inherit from itself\n");
-@@ -4486,594 +4481,594 @@ yyreduce:
- check_async_uuid((yyval.type));
- pointer_default = (yyvsp[-5].ifinfo).old_pointer_default;
- }
--#line 4490 "parser.tab.c" /* yacc.c:1648 */
-+#line 4485 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 310:
--#line 924 "parser.y" /* yacc.c:1648 */
-+#line 922 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-7].ifinfo).interface;
- type_interface_define((yyval.type), find_type_or_error2((yyvsp[-5].str), 0), (yyvsp[-2].stmt_list));
- pointer_default = (yyvsp[-7].ifinfo).old_pointer_default;
- }
--#line 4499 "parser.tab.c" /* yacc.c:1648 */
-+#line 4494 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 311:
--#line 928 "parser.y" /* yacc.c:1648 */
-+#line 926 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-1].type); }
--#line 4505 "parser.tab.c" /* yacc.c:1648 */
-+#line 4500 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 312:
--#line 932 "parser.y" /* yacc.c:1648 */
-+#line 930 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-1].type); }
--#line 4511 "parser.tab.c" /* yacc.c:1648 */
-+#line 4506 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 313:
--#line 933 "parser.y" /* yacc.c:1648 */
-+#line 931 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-1].type); }
--#line 4517 "parser.tab.c" /* yacc.c:1648 */
-+#line 4512 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 314:
--#line 936 "parser.y" /* yacc.c:1648 */
-+#line 934 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_module((yyvsp[0].str)); }
--#line 4523 "parser.tab.c" /* yacc.c:1648 */
-+#line 4518 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 315:
--#line 937 "parser.y" /* yacc.c:1648 */
-+#line 935 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_module((yyvsp[0].str)); }
--#line 4529 "parser.tab.c" /* yacc.c:1648 */
-+#line 4524 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 316:
--#line 940 "parser.y" /* yacc.c:1648 */
-+#line 938 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type);
- (yyval.type)->attrs = check_module_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
- }
--#line 4537 "parser.tab.c" /* yacc.c:1648 */
-+#line 4532 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 317:
--#line 946 "parser.y" /* yacc.c:1648 */
-+#line 944 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[-4].type);
- type_module_define((yyval.type), (yyvsp[-2].stmt_list));
- }
--#line 4545 "parser.tab.c" /* yacc.c:1648 */
-+#line 4540 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 318:
--#line 952 "parser.y" /* yacc.c:1648 */
-+#line 950 "parser.y" /* yacc.c:1646 */
- { (yyval.stgclass) = STG_EXTERN; }
--#line 4551 "parser.tab.c" /* yacc.c:1648 */
-+#line 4546 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 319:
--#line 953 "parser.y" /* yacc.c:1648 */
-+#line 951 "parser.y" /* yacc.c:1646 */
- { (yyval.stgclass) = STG_STATIC; }
--#line 4557 "parser.tab.c" /* yacc.c:1648 */
-+#line 4552 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 320:
--#line 954 "parser.y" /* yacc.c:1648 */
-+#line 952 "parser.y" /* yacc.c:1646 */
- { (yyval.stgclass) = STG_REGISTER; }
--#line 4563 "parser.tab.c" /* yacc.c:1648 */
-+#line 4558 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 321:
--#line 958 "parser.y" /* yacc.c:1648 */
-- { (yyval.attr) = make_attr(ATTR_INLINE); }
--#line 4569 "parser.tab.c" /* yacc.c:1648 */
-+#line 956 "parser.y" /* yacc.c:1646 */
-+ { (yyval.funcspecifier) = FUNCTION_SPECIFIER_INLINE; }
-+#line 4564 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 322:
--#line 962 "parser.y" /* yacc.c:1648 */
-- { (yyval.attr) = make_attr(ATTR_CONST); }
--#line 4575 "parser.tab.c" /* yacc.c:1648 */
-+#line 960 "parser.y" /* yacc.c:1646 */
-+ { (yyval.typequalifier) = TYPE_QUALIFIER_CONST; }
-+#line 4570 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 323:
--#line 965 "parser.y" /* yacc.c:1648 */
-- { (yyval.attr_list) = NULL; }
--#line 4581 "parser.tab.c" /* yacc.c:1648 */
-+#line 963 "parser.y" /* yacc.c:1646 */
-+ { (yyval.typequalifier) = TYPE_QUALIFIER_NONE; }
-+#line 4576 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 324:
--#line 966 "parser.y" /* yacc.c:1648 */
-- { (yyval.attr_list) = append_attr((yyvsp[-1].attr_list), (yyvsp[0].attr)); }
--#line 4587 "parser.tab.c" /* yacc.c:1648 */
-+#line 964 "parser.y" /* yacc.c:1646 */
-+ { (yyval.typequalifier) = (yyvsp[-1].typequalifier) | (yyvsp[0].typequalifier); }
-+#line 4582 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 325:
--#line 969 "parser.y" /* yacc.c:1648 */
-- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, NULL, STG_NONE); }
--#line 4593 "parser.tab.c" /* yacc.c:1648 */
-+#line 967 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
-+#line 4588 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 326:
--#line 971 "parser.y" /* yacc.c:1648 */
-- { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), NULL, STG_NONE); }
--#line 4599 "parser.tab.c" /* yacc.c:1648 */
-+#line 969 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
-+#line 4594 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 327:
--#line 974 "parser.y" /* yacc.c:1648 */
-+#line 972 "parser.y" /* yacc.c:1646 */
- { (yyval.declspec) = NULL; }
--#line 4605 "parser.tab.c" /* yacc.c:1648 */
-+#line 4600 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 329:
--#line 979 "parser.y" /* yacc.c:1648 */
-- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
--#line 4611 "parser.tab.c" /* yacc.c:1648 */
-+#line 977 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, (yyvsp[-1].typequalifier), FUNCTION_SPECIFIER_NONE); }
-+#line 4606 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 330:
--#line 980 "parser.y" /* yacc.c:1648 */
-- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); }
--#line 4617 "parser.tab.c" /* yacc.c:1648 */
-+#line 978 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, STG_NONE, TYPE_QUALIFIER_NONE, (yyvsp[-1].funcspecifier)); }
-+#line 4612 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 331:
--#line 981 "parser.y" /* yacc.c:1648 */
-- { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, NULL, (yyvsp[-1].stgclass)); }
--#line 4623 "parser.tab.c" /* yacc.c:1648 */
-+#line 979 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].stgclass), TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
-+#line 4618 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 332:
--#line 986 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
--#line 4629 "parser.tab.c" /* yacc.c:1648 */
-+#line 984 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
-+#line 4624 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 333:
--#line 987 "parser.y" /* yacc.c:1648 */
-+#line 985 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
-- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
--#line 4636 "parser.tab.c" /* yacc.c:1648 */
-+ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
-+#line 4631 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 335:
--#line 993 "parser.y" /* yacc.c:1648 */
-+#line 991 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
--#line 4642 "parser.tab.c" /* yacc.c:1648 */
-+#line 4637 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 336:
--#line 994 "parser.y" /* yacc.c:1648 */
-+#line 992 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-1].declarator); }
--#line 4648 "parser.tab.c" /* yacc.c:1648 */
-+#line 4643 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 337:
--#line 995 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
--#line 4654 "parser.tab.c" /* yacc.c:1648 */
-+#line 993 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
-+#line 4649 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 338:
--#line 996 "parser.y" /* yacc.c:1648 */
-+#line 994 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-3].declarator);
-- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
-- (yyval.declarator)->type = NULL;
-+ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
-+ (yyval.declarator)->declspec.type = NULL;
- }
--#line 4663 "parser.tab.c" /* yacc.c:1648 */
-+#line 4658 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 339:
--#line 1005 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
--#line 4669 "parser.tab.c" /* yacc.c:1648 */
-+#line 1003 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
-+#line 4664 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 340:
--#line 1006 "parser.y" /* yacc.c:1648 */
-+#line 1004 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
-- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
--#line 4676 "parser.tab.c" /* yacc.c:1648 */
-+ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
-+#line 4671 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 342:
--#line 1014 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
--#line 4682 "parser.tab.c" /* yacc.c:1648 */
-+#line 1012 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
-+#line 4677 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 343:
--#line 1015 "parser.y" /* yacc.c:1648 */
-+#line 1013 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[0].declarator); if ((yyval.declarator)->func_type) (yyval.declarator)->func_type->attrs = append_attr((yyval.declarator)->func_type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str)));
-- else if ((yyval.declarator)->type) (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
--#line 4689 "parser.tab.c" /* yacc.c:1648 */
-+ else if ((yyval.declarator)->declspec.type) (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
-+#line 4684 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 344:
--#line 1020 "parser.y" /* yacc.c:1648 */
-+#line 1018 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = make_declarator(NULL); }
--#line 4695 "parser.tab.c" /* yacc.c:1648 */
-+#line 4690 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 346:
--#line 1026 "parser.y" /* yacc.c:1648 */
-+#line 1024 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-1].declarator); }
--#line 4701 "parser.tab.c" /* yacc.c:1648 */
-+#line 4696 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 347:
--#line 1027 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
--#line 4707 "parser.tab.c" /* yacc.c:1648 */
-+#line 1025 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
-+#line 4702 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 348:
--#line 1028 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
--#line 4713 "parser.tab.c" /* yacc.c:1648 */
-+#line 1026 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
-+#line 4708 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 349:
--#line 1030 "parser.y" /* yacc.c:1648 */
-+#line 1028 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = make_declarator(NULL);
-- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
-- (yyval.declarator)->type = NULL;
-+ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
-+ (yyval.declarator)->declspec.type = NULL;
- }
--#line 4722 "parser.tab.c" /* yacc.c:1648 */
-+#line 4717 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 350:
--#line 1035 "parser.y" /* yacc.c:1648 */
-+#line 1033 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-3].declarator);
-- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
-- (yyval.declarator)->type = NULL;
-+ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
-+ (yyval.declarator)->declspec.type = NULL;
- }
--#line 4731 "parser.tab.c" /* yacc.c:1648 */
-+#line 4726 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 351:
--#line 1044 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
--#line 4737 "parser.tab.c" /* yacc.c:1648 */
-+#line 1042 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
-+#line 4732 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 352:
--#line 1045 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
--#line 4743 "parser.tab.c" /* yacc.c:1648 */
-+#line 1043 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
-+#line 4738 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 354:
--#line 1052 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_chain_type((yyval.declarator)->type, type_new_pointer(pointer_default, NULL, (yyvsp[-1].attr_list))); }
--#line 4749 "parser.tab.c" /* yacc.c:1648 */
-+#line 1050 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[0].declarator); append_chain_declspec(&(yyval.declarator)->declspec, type_new_pointer(pointer_default, NULL), (yyvsp[-1].typequalifier)); }
-+#line 4744 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 355:
--#line 1053 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
--#line 4755 "parser.tab.c" /* yacc.c:1648 */
-+#line 1051 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->declspec.type->attrs = append_attr((yyval.declarator)->declspec.type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); }
-+#line 4750 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 356:
--#line 1057 "parser.y" /* yacc.c:1648 */
-+#line 1055 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = make_declarator(NULL); }
--#line 4761 "parser.tab.c" /* yacc.c:1648 */
-+#line 4756 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 358:
--#line 1065 "parser.y" /* yacc.c:1648 */
-+#line 1063 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = make_declarator((yyvsp[0].var)); }
--#line 4767 "parser.tab.c" /* yacc.c:1648 */
-+#line 4762 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 359:
--#line 1066 "parser.y" /* yacc.c:1648 */
-+#line 1064 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-1].declarator); }
--#line 4773 "parser.tab.c" /* yacc.c:1648 */
-+#line 4768 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 360:
--#line 1067 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
--#line 4779 "parser.tab.c" /* yacc.c:1648 */
-+#line 1065 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
-+#line 4774 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 361:
--#line 1068 "parser.y" /* yacc.c:1648 */
-- { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->type = append_array((yyval.declarator)->type, (yyvsp[0].expr)); }
--#line 4785 "parser.tab.c" /* yacc.c:1648 */
-+#line 1066 "parser.y" /* yacc.c:1646 */
-+ { (yyval.declarator) = make_declarator(NULL); (yyval.declarator)->declspec.type = append_array((yyval.declarator)->declspec.type, (yyvsp[0].expr)); }
-+#line 4780 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 362:
--#line 1070 "parser.y" /* yacc.c:1648 */
-+#line 1068 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = make_declarator(NULL);
-- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
-- (yyval.declarator)->type = NULL;
-+ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
-+ (yyval.declarator)->declspec.type = NULL;
- }
--#line 4794 "parser.tab.c" /* yacc.c:1648 */
-+#line 4789 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 363:
--#line 1075 "parser.y" /* yacc.c:1648 */
-+#line 1073 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-3].declarator);
-- (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->type, type_new_function((yyvsp[-1].var_list)));
-- (yyval.declarator)->type = NULL;
-+ (yyval.declarator)->func_type = append_chain_type((yyval.declarator)->declspec.type, type_new_function((yyvsp[-1].var_list)));
-+ (yyval.declarator)->declspec.type = NULL;
- }
--#line 4803 "parser.tab.c" /* yacc.c:1648 */
-+#line 4798 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 364:
--#line 1082 "parser.y" /* yacc.c:1648 */
-+#line 1080 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
--#line 4809 "parser.tab.c" /* yacc.c:1648 */
-+#line 4804 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 365:
--#line 1083 "parser.y" /* yacc.c:1648 */
-+#line 1081 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
--#line 4815 "parser.tab.c" /* yacc.c:1648 */
-+#line 4810 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 366:
--#line 1086 "parser.y" /* yacc.c:1648 */
-+#line 1084 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = NULL; }
--#line 4821 "parser.tab.c" /* yacc.c:1648 */
-+#line 4816 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 367:
--#line 1087 "parser.y" /* yacc.c:1648 */
-+#line 1085 "parser.y" /* yacc.c:1646 */
- { (yyval.expr) = (yyvsp[0].expr); }
--#line 4827 "parser.tab.c" /* yacc.c:1648 */
-+#line 4822 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 368:
--#line 1090 "parser.y" /* yacc.c:1648 */
-+#line 1088 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->bits = (yyvsp[0].expr);
- if (!(yyval.declarator)->bits && !(yyval.declarator)->var->name)
- error_loc("unnamed fields are not allowed\n");
- }
--#line 4836 "parser.tab.c" /* yacc.c:1648 */
-+#line 4831 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 369:
--#line 1097 "parser.y" /* yacc.c:1648 */
-+#line 1095 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); }
--#line 4842 "parser.tab.c" /* yacc.c:1648 */
-+#line 4837 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 370:
--#line 1099 "parser.y" /* yacc.c:1648 */
-+#line 1097 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); }
--#line 4848 "parser.tab.c" /* yacc.c:1648 */
-+#line 4843 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 371:
--#line 1103 "parser.y" /* yacc.c:1648 */
-+#line 1101 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[0].declarator); }
--#line 4854 "parser.tab.c" /* yacc.c:1648 */
-+#line 4849 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 372:
--#line 1104 "parser.y" /* yacc.c:1648 */
-+#line 1102 "parser.y" /* yacc.c:1646 */
- { (yyval.declarator) = (yyvsp[-2].declarator); (yyvsp[-2].declarator)->var->eval = (yyvsp[0].expr); }
--#line 4860 "parser.tab.c" /* yacc.c:1648 */
-+#line 4855 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 373:
--#line 1108 "parser.y" /* yacc.c:1648 */
-+#line 1106 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = THREADING_APARTMENT; }
--#line 4866 "parser.tab.c" /* yacc.c:1648 */
-+#line 4861 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 374:
--#line 1109 "parser.y" /* yacc.c:1648 */
-+#line 1107 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = THREADING_NEUTRAL; }
--#line 4872 "parser.tab.c" /* yacc.c:1648 */
-+#line 4867 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 375:
--#line 1110 "parser.y" /* yacc.c:1648 */
-+#line 1108 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = THREADING_SINGLE; }
--#line 4878 "parser.tab.c" /* yacc.c:1648 */
-+#line 4873 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 376:
--#line 1111 "parser.y" /* yacc.c:1648 */
-+#line 1109 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = THREADING_FREE; }
--#line 4884 "parser.tab.c" /* yacc.c:1648 */
-+#line 4879 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 377:
--#line 1112 "parser.y" /* yacc.c:1648 */
-+#line 1110 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = THREADING_BOTH; }
--#line 4890 "parser.tab.c" /* yacc.c:1648 */
-+#line 4885 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 378:
--#line 1116 "parser.y" /* yacc.c:1648 */
-+#line 1114 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = FC_RP; }
--#line 4896 "parser.tab.c" /* yacc.c:1648 */
-+#line 4891 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 379:
--#line 1117 "parser.y" /* yacc.c:1648 */
-+#line 1115 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = FC_UP; }
--#line 4902 "parser.tab.c" /* yacc.c:1648 */
-+#line 4897 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 380:
--#line 1118 "parser.y" /* yacc.c:1648 */
-+#line 1116 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = FC_FP; }
--#line 4908 "parser.tab.c" /* yacc.c:1648 */
-+#line 4903 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 381:
--#line 1121 "parser.y" /* yacc.c:1648 */
-+#line 1119 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_struct((yyvsp[-3].str), current_namespace, TRUE, (yyvsp[-1].var_list)); }
--#line 4914 "parser.tab.c" /* yacc.c:1648 */
-+#line 4909 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 382:
--#line 1124 "parser.y" /* yacc.c:1648 */
-+#line 1122 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_void(); }
--#line 4920 "parser.tab.c" /* yacc.c:1648 */
-+#line 4915 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 383:
--#line 1125 "parser.y" /* yacc.c:1648 */
-+#line 1123 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = find_type_or_error((yyvsp[0].str), 0); }
--#line 4926 "parser.tab.c" /* yacc.c:1648 */
-+#line 4921 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 384:
--#line 1126 "parser.y" /* yacc.c:1648 */
-+#line 1124 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type); }
--#line 4932 "parser.tab.c" /* yacc.c:1648 */
-+#line 4927 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 385:
--#line 1127 "parser.y" /* yacc.c:1648 */
-+#line 1125 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type); }
--#line 4938 "parser.tab.c" /* yacc.c:1648 */
-+#line 4933 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 386:
--#line 1128 "parser.y" /* yacc.c:1648 */
-+#line 1126 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_enum((yyvsp[0].str), current_namespace, FALSE, NULL); }
--#line 4944 "parser.tab.c" /* yacc.c:1648 */
-+#line 4939 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 387:
--#line 1129 "parser.y" /* yacc.c:1648 */
-+#line 1127 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type); }
--#line 4950 "parser.tab.c" /* yacc.c:1648 */
-+#line 4945 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 388:
--#line 1130 "parser.y" /* yacc.c:1648 */
-+#line 1128 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_struct((yyvsp[0].str), current_namespace, FALSE, NULL); }
--#line 4956 "parser.tab.c" /* yacc.c:1648 */
-+#line 4951 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 389:
--#line 1131 "parser.y" /* yacc.c:1648 */
-+#line 1129 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = (yyvsp[0].type); }
--#line 4962 "parser.tab.c" /* yacc.c:1648 */
-+#line 4957 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 390:
--#line 1132 "parser.y" /* yacc.c:1648 */
-+#line 1130 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_nonencapsulated_union((yyvsp[0].str), FALSE, NULL); }
--#line 4968 "parser.tab.c" /* yacc.c:1648 */
-+#line 4963 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 391:
--#line 1133 "parser.y" /* yacc.c:1648 */
-+#line 1131 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = make_safearray((yyvsp[-1].type)); }
--#line 4974 "parser.tab.c" /* yacc.c:1648 */
-+#line 4969 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 392:
--#line 1137 "parser.y" /* yacc.c:1648 */
-+#line 1135 "parser.y" /* yacc.c:1646 */
- { (yyvsp[-4].attr_list) = append_attribs((yyvsp[-4].attr_list), (yyvsp[-2].attr_list));
- reg_typedefs((yyvsp[-1].declspec), (yyvsp[0].declarator_list), check_typedef_attrs((yyvsp[-4].attr_list)));
- (yyval.statement) = make_statement_typedef((yyvsp[0].declarator_list));
- }
--#line 4983 "parser.tab.c" /* yacc.c:1648 */
-+#line 4978 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 393:
--#line 1144 "parser.y" /* yacc.c:1648 */
-+#line 1142 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_nonencapsulated_union((yyvsp[-3].str), TRUE, (yyvsp[-1].var_list)); }
--#line 4989 "parser.tab.c" /* yacc.c:1648 */
-+#line 4984 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 394:
--#line 1147 "parser.y" /* yacc.c:1648 */
-+#line 1145 "parser.y" /* yacc.c:1646 */
- { (yyval.type) = type_new_encapsulated_union((yyvsp[-8].str), (yyvsp[-5].var), (yyvsp[-3].var), (yyvsp[-1].var_list)); }
--#line 4995 "parser.tab.c" /* yacc.c:1648 */
-+#line 4990 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 395:
--#line 1151 "parser.y" /* yacc.c:1648 */
-+#line 1149 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); }
--#line 5001 "parser.tab.c" /* yacc.c:1648 */
-+#line 4996 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 396:
--#line 1152 "parser.y" /* yacc.c:1648 */
-+#line 1150 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); }
--#line 5007 "parser.tab.c" /* yacc.c:1648 */
-+#line 5002 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 397:
--#line 1153 "parser.y" /* yacc.c:1648 */
-+#line 1151 "parser.y" /* yacc.c:1646 */
- { (yyval.num) = (yyvsp[0].num); }
--#line 5013 "parser.tab.c" /* yacc.c:1648 */
-+#line 5008 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 402:
--#line 1166 "parser.y" /* yacc.c:1648 */
-+#line 1164 "parser.y" /* yacc.c:1646 */
- { type_t *type = find_type_or_error((yyvsp[-1].str), 0);
- type->attrs = append_attr_list(type->attrs, (yyvsp[-2].attr_list));
- }
--#line 5021 "parser.tab.c" /* yacc.c:1648 */
-+#line 5016 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 403:
--#line 1171 "parser.y" /* yacc.c:1648 */
-+#line 1169 "parser.y" /* yacc.c:1646 */
- { type_t *iface = find_type_or_error2((yyvsp[-3].str), 0);
- if (type_get_type(iface) != TYPE_INTERFACE)
- error_loc("%s is not an interface\n", iface->name);
- iface->attrs = append_attr_list(iface->attrs, (yyvsp[-5].attr_list));
- }
--#line 5031 "parser.tab.c" /* yacc.c:1648 */
-+#line 5026 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 404:
--#line 1178 "parser.y" /* yacc.c:1648 */
-+#line 1176 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = NULL; }
--#line 5037 "parser.tab.c" /* yacc.c:1648 */
-+#line 5032 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 405:
--#line 1179 "parser.y" /* yacc.c:1648 */
-+#line 1177 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = (yyvsp[-1].attr_list); }
--#line 5043 "parser.tab.c" /* yacc.c:1648 */
-+#line 5038 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 406:
--#line 1182 "parser.y" /* yacc.c:1648 */
-+#line 1180 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = append_attr(NULL, (yyvsp[0].attr)); }
--#line 5049 "parser.tab.c" /* yacc.c:1648 */
-+#line 5044 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 407:
--#line 1183 "parser.y" /* yacc.c:1648 */
-+#line 1181 "parser.y" /* yacc.c:1646 */
- { (yyval.attr_list) = append_attr((yyvsp[-2].attr_list), (yyvsp[0].attr)); }
--#line 5055 "parser.tab.c" /* yacc.c:1648 */
-+#line 5050 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 408:
--#line 1186 "parser.y" /* yacc.c:1648 */
-+#line 1184 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_ENCODE); }
--#line 5061 "parser.tab.c" /* yacc.c:1648 */
-+#line 5056 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 409:
--#line 1187 "parser.y" /* yacc.c:1648 */
-+#line 1185 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_DECODE); }
--#line 5067 "parser.tab.c" /* yacc.c:1648 */
-+#line 5062 "parser.tab.c" /* yacc.c:1646 */
- break;
-
- case 410:
--#line 1188 "parser.y" /* yacc.c:1648 */
-+#line 1186 "parser.y" /* yacc.c:1646 */
- { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); }
--#line 5073 "parser.tab.c" /* yacc.c:1648 */
-+#line 5068 "parser.tab.c" /* yacc.c:1646 */
- break;
-
-
--#line 5077 "parser.tab.c" /* yacc.c:1648 */
-+#line 5072 "parser.tab.c" /* yacc.c:1646 */
- default: break;
- }
- /* User semantic actions sometimes alter yychar, and that requires
-@@ -5301,7 +5296,7 @@ yyreturn:
- #endif
- return yyresult;
- }
--#line 1190 "parser.y" /* yacc.c:1907 */
-+#line 1188 "parser.y" /* yacc.c:1906 */
-
-
- static void decl_builtin_basic(const char *name, enum type_basic_type type)
-@@ -5312,7 +5307,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
-
- static void decl_builtin_alias(const char *name, type_t *t)
- {
-- reg_type(type_new_alias(t, name), name, NULL, 0);
-+ decl_spec_t ds;
-+ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
- }
-
- void init_types(void)
-@@ -5323,7 +5319,7 @@ void init_types(void)
- decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
- decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
- decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
-- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
-+ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
- }
-
- static str_list_t *append_str(str_list_t *list, char *str)
-@@ -5354,6 +5350,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
- LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
- if (attr_existing->type == attr->type)
- {
-+ __builtin_trap();
- parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
- /* use the last attribute, like MIDL does */
- list_remove(&attr_existing->entry);
-@@ -5413,53 +5410,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
- return new_list;
- }
-
--static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
-+static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
- {
- decl_spec_t *declspec = left ? left : right;
- if (!declspec)
- {
- declspec = xmalloc(sizeof(*declspec));
- declspec->type = NULL;
-- declspec->attrs = NULL;
- declspec->stgclass = STG_NONE;
-+ declspec->typequalifier = TYPE_QUALIFIER_NONE;
-+ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
- }
- declspec->type = type;
- if (left && declspec != left)
- {
-- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = left->stgclass;
- else if (left->stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
-+
-+ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
-+ declspec->typequalifier = left->typequalifier;
-+ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
-+ error_loc("only one type qualifier can be specified\n");
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
-+ declspec->funcspecifier = left->funcspecifier;
-+ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
-+ error_loc("only one function specifier can be specified\n");
-+
- assert(!left->type);
- free(left);
- }
- if (right && declspec != right)
- {
-- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = right->stgclass;
- else if (right->stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
-+
-+ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
-+ declspec->typequalifier = right->typequalifier;
-+ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
-+ error_loc("only one type qualifier can be specified\n");
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
-+ declspec->funcspecifier = right->funcspecifier;
-+ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
-+ error_loc("only one function specifier can be specified\n");
-+
- assert(!right->type);
- free(right);
- }
-
-- declspec->attrs = append_attr(declspec->attrs, attr);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = stgclass;
- else if (stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
-
-- /* apply attributes to type */
-- if (type && declspec->attrs)
-- {
-- attr_list_t *attrs;
-- declspec->type = duptype(type, 1);
-- attrs = map_attrs(type->attrs, NULL);
-- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
-- declspec->attrs = NULL;
-- }
-+ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
-+ declspec->typequalifier = typequalifier;
-+ else if (typequalifier != TYPE_QUALIFIER_NONE)
-+ error_loc("only one type qualifier can be specified\n");
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
-+ declspec->funcspecifier = funcspecifier;
-+ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
-+ error_loc("only one function specifier can be specified\n");
-
- return declspec;
- }
-@@ -5545,6 +5562,7 @@ void clear_all_offsets(void)
-
- static void type_function_add_head_arg(type_t *type, var_t *arg)
- {
-+ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
- if (!type->details.function->args)
- {
- type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
-@@ -5589,31 +5607,60 @@ static int is_allowed_range_type(const type_t *type)
- static type_t *get_array_or_ptr_ref(type_t *type)
- {
- if (is_ptr(type))
-- return type_pointer_get_ref(type);
-+ return type_pointer_get_ref_type(type);
- else if (is_array(type))
-- return type_array_get_element(type);
-+ return type_array_get_element_type(type);
- return NULL;
- }
-
- static type_t *append_chain_type(type_t *chain, type_t *type)
- {
-- type_t *chain_type;
-+ type_t *chain_type = NULL;
-
- if (!chain)
- return type;
- for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
- ;
-
-+ assert(!type_is_alias(chain_type));
- if (is_ptr(chain_type))
-- chain_type->details.pointer.ref = type;
-+ chain_type->details.pointer.ref.type = type;
- else if (is_array(chain_type))
-- chain_type->details.array.elem = type;
-+ chain_type->details.array.elem.type = type;
- else
- assert(0);
-
- return chain;
- }
-
-+static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
-+{
-+ type_t *chain_type = chain->type;
-+ decl_spec_t *chain_declspec = NULL;
-+
-+ if (!chain_type)
-+ {
-+ chain->type = type;
-+ chain->typequalifier = typequalifier;
-+ return chain;
-+ }
-+
-+ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
-+ ;
-+
-+ if (is_ptr(chain_type))
-+ chain_declspec = &chain_type->details.pointer.ref;
-+ else if (is_array(chain_type))
-+ chain_declspec = &chain_type->details.array.elem;
-+ else
-+ assert(NULL);
-+
-+ chain_declspec->type = type;
-+ chain_declspec->typequalifier = typequalifier;
-+
-+ return chain;
-+}
-+
- static warning_list_t *append_warning(warning_list_t *list, int num)
- {
- warning_t *entry;
-@@ -5629,7 +5676,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
- return list;
- }
-
--static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
-+static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
- int top)
- {
- var_t *v = decl->var;
-@@ -5638,58 +5685,74 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- expr_t *dim;
- type_t **ptype;
- type_t *func_type = decl ? decl->func_type : NULL;
-- type_t *type = decl_spec->type;
-+ type_t *type = declspec->type;
-
-- if (is_attr(type->attrs, ATTR_INLINE))
-- {
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
- if (!func_type)
- error_loc("inline attribute applied to non-function type\n");
- else
- {
-- type_t *t;
-- /* move inline attribute from return type node to function node */
-- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
-- ;
-- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
-+ v->declspec.funcspecifier = declspec->funcspecifier;
- }
- }
-
-- /* 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;
-+ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
-+ * unless the pointee already has const type qualifier*/
-+ if (!decl)
-+ {
-+ /* simplest case, no pointers to deal with here */
-+ v->declspec.typequalifier = declspec->typequalifier;
-+ } else if (decl->bits)
-+ {
-+ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
-+ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
-+ v->declspec.typequalifier = declspec->typequalifier;
-+ }
-+ else
-+ {
-+ /* here we're dealing with a pointerish type chain, so we need to pull
-+ * the typequalifier off of the declspec and stick them in the type's attr list
-+ */
-+ v->declspec.type = decl->declspec.type;
-+ v->declspec.typequalifier = decl->declspec.typequalifier;
-+ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
-+ }
-+
-+ v->declspec.stgclass = declspec->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);
- if (!ptr_attr && type_is_alias(ptr))
-- ptr = type_alias_get_aliasee(ptr);
-+ ptr = type_alias_get_aliasee_type(ptr);
- else
- break;
- }
- if (is_ptr(ptr))
- {
- if (ptr_attr && ptr_attr != FC_UP &&
-- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
-+ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
- warning_loc_info(&v->loc_info,
- "%s: pointer attribute applied to interface "
- "pointer type has no effect\n", v->name);
-- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
-+ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
- {
- /* FIXME: this is a horrible hack to cope with the issue that we
- * store an offset to the typeformat string in the type object, but
- * two typeformat strings may be written depending on whether the
- * pointer is a toplevel parameter or not */
-- *pt = duptype(*pt, 1);
-+ *pt = dup_pointer_type(*pt);
- }
- }
- else if (ptr_attr)
-@@ -5700,16 +5763,16 @@ 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);
-
- for (;;)
- {
- if (is_ptr(t))
-- t = type_pointer_get_ref(t);
-+ t = type_pointer_get_ref_type(t);
- else if (is_array(t))
-- t = type_array_get_element(t);
-+ t = type_array_get_element_type(t);
- else
- break;
- }
-@@ -5726,15 +5789,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)
-@@ -5747,7 +5810,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- else
- *ptype = type_new_array((*ptype)->name,
- type_array_get_element(*ptype), FALSE,
-- 0, dim, NULL, 0);
-+ 0, dim, NULL, FC_RP);
- }
- else if (is_ptr(*ptype))
- *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
-@@ -5756,15 +5819,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- error_loc("%s: size_is attribute applied to illegal type\n", v->name);
- }
-
-+ assert(!type_is_alias(*ptype));
- if (is_ptr(*ptype))
-- ptype = &(*ptype)->details.pointer.ref;
-+ ptype = &(*ptype)->details.pointer.ref.type;
- else if (is_array(*ptype))
-- ptype = &(*ptype)->details.array.elem;
-+ ptype = &(*ptype)->details.array.elem.type;
- else
- 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)
-@@ -5782,10 +5846,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- error_loc("%s: length_is attribute applied to illegal type\n", v->name);
- }
-
-+ assert(!type_is_alias(*ptype));
- if (is_ptr(*ptype))
-- ptype = &(*ptype)->details.pointer.ref;
-+ ptype = &(*ptype)->details.pointer.ref.type;
- else if (is_array(*ptype))
-- ptype = &(*ptype)->details.array.elem;
-+ ptype = &(*ptype)->details.array.elem.type;
- else
- error_loc("%s: too many expressions in length_is attribute\n", v->name);
- }
-@@ -5796,29 +5861,31 @@ 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;
-+ enum type_qualifier typequalifier = v->declspec.typequalifier;
-+
-+ v->declspec.type = func_type;
-+ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
-+ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(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;
-+ ft->details.function->retval->declspec.typequalifier = typequalifier;
-+
- /* 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_type(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_type(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);
--
- return v;
- }
-
-@@ -5866,6 +5933,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
- list_init( list );
- }
- list_add_tail( list, &var->entry );
-+
-+ if (var->declspec.type)
-+ var->declonly = !type_is_defined(var->declspec.type);
-+
- return list;
- }
-
-@@ -5885,11 +5956,11 @@ 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);
-+ v->declonly = TRUE;
- return v;
- }
-
-@@ -5897,10 +5968,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;
- }
-@@ -5920,7 +5990,7 @@ static declarator_t *make_declarator(var_t *var)
- {
- declarator_t *d = xmalloc(sizeof(*d));
- d->var = var ? var : make_var(NULL);
-- d->type = NULL;
-+ init_declspec(&d->declspec, NULL);
- d->func_type = NULL;
- d->bits = NULL;
- return d;
-@@ -5928,7 +5998,15 @@ static declarator_t *make_declarator(var_t *var)
-
- static type_t *make_safearray(type_t *type)
- {
-- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
-+ decl_spec_t aliasee_ds;
-+ decl_spec_t element_ds;
-+
-+ init_declspec(&element_ds,
-+ type_new_alias(
-+ init_declspec(&aliasee_ds, type),
-+ "SAFEARRAY"));
-+
-+ return type_new_array(NULL, &element_ds, TRUE, 0,
- NULL, NULL, FC_RP);
- }
-
-@@ -6018,15 +6096,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
- nt->t = t;
- nt->next = namespace->type_hash[hash];
- namespace->type_hash[hash] = nt;
-- if ((t == tsSTRUCT || t == tsUNION))
-+ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
- fix_incomplete_types(type);
- return type;
- }
-
- static int is_incomplete(const type_t *t)
- {
-- return !t->defined &&
-- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
-+ return !type_is_defined(t) &&
-+ (type_get_type_detect_alias(t) == TYPE_ENUM ||
-+ type_get_type_detect_alias(t) == TYPE_STRUCT ||
- type_get_type_detect_alias(t) == TYPE_UNION ||
- type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
- }
-@@ -6034,19 +6113,16 @@ static int is_incomplete(const type_t *t)
- void add_incomplete(type_t *t)
- {
- struct typenode *tn = xmalloc(sizeof *tn);
-+ assert(is_incomplete(t));
- tn->type = t;
- list_add_tail(&incomplete_types, &tn->entry);
- }
-
- static void fix_type(type_t *t)
- {
-- if (type_is_alias(t) && is_incomplete(t)) {
-- type_t *ot = type_alias_get_aliasee(t);
-- fix_type(ot);
-- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
-- type_get_type_detect_alias(ot) == TYPE_UNION ||
-- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
-- t->details.structure = ot->details.structure;
-+ if (type_is_alias(t) && is_incomplete(t))
-+ {
-+ type_t *ot = type_alias_get_aliasee_type(t);
- t->defined = ot->defined;
- }
- }
-@@ -6070,7 +6146,7 @@ static void fix_incomplete_types(type_t *complete_type)
- {
- if (type_is_equal(complete_type, tn->type))
- {
-- tn->type->details.structure = complete_type->details.structure;
-+ tn->type->details = complete_type->details;
- list_remove(&tn->entry);
- free(tn);
- }
-@@ -6094,7 +6170,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
- type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
- {
- if (!type->name)
-+ {
- type->name = gen_name();
-+ /* the generated name will be used and this typedef excluded from the
-+ * built typelib unless the typedef has the 'public' attribute, so add it here */
-+ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
-+ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
-+ }
-
- /* replace existing attributes when generating a typelib */
- if (do_typelib)
-@@ -6125,7 +6207,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, name->name);
- cur->attrs = attrs;
-
- if (is_incomplete(cur))
-@@ -6293,7 +6375,6 @@ struct allowed_attr allowed_attr[] =
- /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
- /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
- /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
-- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
- /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
- /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
- /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
-@@ -6328,7 +6409,6 @@ struct allowed_attr allowed_attr[] =
- /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
- /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
- /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
-- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
- /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
- /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
- /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
-@@ -6400,10 +6480,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);
-@@ -6608,7 +6688,7 @@ static int is_ptr_guid_type(const type_t *type)
-
- /* second, make sure it is a pointer to something of size sizeof(GUID),
- * i.e. 16 bytes */
-- return (type_memsize(type_pointer_get_ref(type)) == 16);
-+ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
- }
-
- static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
-@@ -6635,7 +6715,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;
-@@ -6665,7 +6745,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);
-@@ -6762,23 +6842,28 @@ static void check_field_common(const type_t *container_type,
- {
- const type_t *t = type;
- while (is_ptr(t))
-- t = type_pointer_get_ref(t);
-+ t = type_pointer_get_ref_type(t);
- if (is_aliaschain_attr(t, ATTR_RANGE))
- warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
- break;
- }
- case TGT_POINTER:
-- type = type_pointer_get_ref(type);
-+ type = type_pointer_get_ref_type(type);
- more_to_do = TRUE;
- break;
- case TGT_ARRAY:
-- type = type_array_get_element(type);
-+ type = type_array_get_element_type(type);
- more_to_do = TRUE;
- break;
-+ case TGT_ENUM:
-+ type = type_get_real_type(type);
-+ if(!type_is_complete(type))
-+ {
-+ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
-+ }
- case TGT_USER_TYPE:
- case TGT_IFACE_POINTER:
- case TGT_BASIC:
-- case TGT_ENUM:
- case TGT_RANGE:
- /* nothing to do */
- break;
-@@ -6803,13 +6888,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
- if (type_is_complete(type))
- fields = type_struct_get_fields(type);
- else
-- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
-+ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
- }
- else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
-- fields = type_union_get_cases(type);
-+ {
-+ if (type_is_complete(type))
-+ fields = type_union_get_cases(type);
-+ else
-+ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
-+ }
-
- if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
-- if (field->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 */
-@@ -6818,9 +6908,10 @@ 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 )
-+ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
-+ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
- {
-- const type_t *type = arg->type;
-+ const type_t *type = arg->declspec.type;
-
- /* check that [out] parameters have enough pointer levels */
- if (is_attr(arg->attrs, ATTR_OUT))
-@@ -6860,16 +6951,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);
- }
- }
-@@ -6886,8 +6977,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);
- }
- }
-
-@@ -6952,6 +7043,7 @@ static void check_async_uuid(type_t *iface)
- type_t *async_iface;
- type_t *inherit;
-
-+ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
- if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
-
- inherit = iface->details.iface->inherit;
-@@ -6968,7 +7060,8 @@ 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;
-+ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
-+ args = func->declspec.type->details.function->args;
- if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
- {
- if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
-@@ -6978,15 +7071,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));
- }
-
-@@ -7026,6 +7119,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
- static void check_all_user_types(const statement_list_t *stmts)
- {
- const statement_t *stmt;
-+ const var_t *v;
-
- if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
- {
-@@ -7037,7 +7131,11 @@ 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;
-- check_for_additional_prototype_types(func->type->details.function->args);
-+ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
-+ if (func->declspec.type->details.function->args)
-+ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
-+ check_for_additional_prototype_types(v->declspec.type);
-+ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
- }
- }
- }
-@@ -7071,6 +7169,10 @@ static statement_t *make_statement_type_decl(type_t *type)
- {
- statement_t *stmt = make_statement(STMT_TYPE);
- stmt->u.type = type;
-+ if (type_is_defined(type))
-+ {
-+ stmt->declonly = FALSE;
-+ }
- return stmt;
- }
-
-@@ -7085,16 +7187,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;
- }
-@@ -7146,6 +7248,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
- declarator_t *decl, *next;
- statement_t *stmt;
- type_list_t **type_list;
-+ int defined = TRUE;
-
- if (!decls) return NULL;
-
-@@ -7157,6 +7260,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
- {
- var_t *var = decl->var;
- type_t *type = find_type_or_error(var->name, 0);
-+
-+ /* ensure that all of the types in this typedef statement have been defined
-+ * before setting its declonly flag */
-+ if (type_is_pointerish(type))
-+ {
-+ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
-+ }
-+ else
-+ {
-+ defined = defined & type_is_defined(type_get_real_type(type));
-+ }
-+
- *type_list = xmalloc(sizeof(type_list_t));
- (*type_list)->type = type;
- (*type_list)->next = NULL;
-@@ -7166,6 +7281,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
- free(var);
- }
-
-+ stmt->declonly = !defined;
- return stmt;
- }
-
-@@ -7206,7 +7322,7 @@ void init_loc_info(loc_info_t *i)
-
- static void check_def(const type_t *t)
- {
-- if (t->defined)
-+ if (type_is_defined(t))
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- t->name, t->loc_info.input_name, t->loc_info.line_number);
- }
-diff --git a/mingw-w64-tools/widl/src/parser.tab.h b/mingw-w64-tools/widl/src/parser.tab.h
-index 09874726..fc7a8f4d 100644
---- a/mingw-w64-tools/widl/src/parser.tab.h
-+++ b/mingw-w64-tools/widl/src/parser.tab.h
-@@ -1,8 +1,8 @@
--/* A Bison parser, made by GNU Bison 3.0.5. */
-+/* A Bison parser, made by GNU Bison 3.0.4. */
-
- /* Bison interface for Yacc-like parsers in C
-
-- Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc.
-+ Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
-@@ -239,7 +239,7 @@ extern int parser_debug;
-
- union YYSTYPE
- {
--#line 142 "parser.y" /* yacc.c:1910 */
-+#line 136 "parser.y" /* yacc.c:1909 */
-
- attr_t *attr;
- attr_list_t *attr_list;
-@@ -266,8 +266,10 @@ union YYSTYPE
- struct _import_t *import;
- struct _decl_spec_t *declspec;
- enum storage_class stgclass;
-+ enum type_qualifier typequalifier;
-+ enum function_specifier funcspecifier;
-
--#line 271 "parser.tab.h" /* yacc.c:1910 */
-+#line 273 "parser.tab.h" /* yacc.c:1909 */
- };
-
- typedef union YYSTYPE YYSTYPE;
-diff --git a/mingw-w64-tools/widl/src/parser.y b/mingw-w64-tools/widl/src/parser.y
-index d9793941..64503ac1 100644
---- a/mingw-w64-tools/widl/src/parser.y
-+++ b/mingw-w64-tools/widl/src/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);
-@@ -67,7 +60,7 @@ static void fix_incomplete_types(type_t *complete_type);
- static str_list_t *append_str(str_list_t *list, char *str);
- static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
- static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
--static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass);
-+static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier);
- static attr_t *make_attr(enum attr_type type);
- static attr_t *make_attrv(enum attr_type type, unsigned int val);
- static attr_t *make_attrp(enum attr_type type, void *val);
-@@ -83,6 +76,7 @@ static declarator_t *make_declarator(var_t *var);
- static type_t *make_safearray(type_t *type);
- static typelib_t *make_library(const char *name, const attr_list_t *attrs);
- static type_t *append_chain_type(type_t *chain, type_t *type);
-+static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier);
- static warning_list_t *append_warning(warning_list_t *, int);
-
- static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
-@@ -165,6 +159,8 @@ static typelib_t *current_typelib;
- struct _import_t *import;
- struct _decl_spec_t *declspec;
- enum storage_class stgclass;
-+ enum type_qualifier typequalifier;
-+ enum function_specifier funcspecifier;
- }
-
- %token <str> aIDENTIFIER aPRAGMA
-@@ -266,14 +262,16 @@ static typelib_t *current_typelib;
- %token tWCHAR tWIREMARSHAL
- %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
-
--%type <attr> attribute type_qualifier function_specifier acf_attribute
--%type <attr_list> m_attributes attributes attrib_list m_type_qual_list
-+%type <attr> attribute acf_attribute
-+%type <attr_list> m_attributes attributes attrib_list
- %type <attr_list> acf_attributes acf_attribute_list
- %type <str_list> str_list
- %type <expr> m_expr expr expr_const expr_int_const array m_bitfield
- %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
- %type <ifinfo> interfacehdr
- %type <stgclass> storage_cls_spec
-+%type <typequalifier> type_qualifier m_type_qual_bits
-+%type <funcspecifier> function_specifier
- %type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
- %type <type> inherit interface interfacedef interfacedec
- %type <type> dispinterface dispinterfacehdr dispinterfacedef
-@@ -318,7 +316,7 @@ static typelib_t *current_typelib;
- %right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
- %left '.' MEMBERPTR '[' ']'
-
--%error-verbose
-+%define parse.error verbose
-
- %%
-
-@@ -651,10 +649,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 +738,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 +762,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);
- }
-@@ -955,20 +953,20 @@ storage_cls_spec:
- ;
-
- function_specifier:
-- tINLINE { $$ = make_attr(ATTR_INLINE); }
-+ tINLINE { $$ = FUNCTION_SPECIFIER_INLINE; }
- ;
-
- type_qualifier:
-- tCONST { $$ = make_attr(ATTR_CONST); }
-+ tCONST { $$ = TYPE_QUALIFIER_CONST; }
- ;
-
--m_type_qual_list: { $$ = NULL; }
-- | m_type_qual_list type_qualifier { $$ = append_attr($1, $2); }
-+m_type_qual_bits: { $$ = TYPE_QUALIFIER_NONE; }
-+ | m_type_qual_bits type_qualifier { $$ = $1 | $2; }
- ;
-
--decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); }
-+decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
- | decl_spec_no_type type m_decl_spec_no_type
-- { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); }
-+ { $$ = make_decl_spec($2, $1, $3, STG_NONE, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
- ;
-
- m_decl_spec_no_type: { $$ = NULL; }
-@@ -976,44 +974,44 @@ m_decl_spec_no_type: { $$ = NULL; }
- ;
-
- decl_spec_no_type:
-- type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
-- | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); }
-- | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); }
-+ type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, $1, FUNCTION_SPECIFIER_NONE); }
-+ | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, STG_NONE, TYPE_QUALIFIER_NONE, $1); }
-+ | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, TYPE_QUALIFIER_NONE, FUNCTION_SPECIFIER_NONE); }
- ;
-
- declarator:
-- '*' m_type_qual_list declarator %prec PPTR
-- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
-+ '*' m_type_qual_bits declarator %prec PPTR
-+ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
- | callconv declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
-- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
-+ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- | direct_declarator
- ;
-
- direct_declarator:
- ident { $$ = make_declarator($1); }
- | '(' declarator ')' { $$ = $2; }
-- | direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
-+ | direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
- | direct_declarator '(' m_args ')' { $$ = $1;
-- $$->func_type = append_chain_type($$->type, type_new_function($3));
-- $$->type = NULL;
-+ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
-+ $$->declspec.type = NULL;
- }
- ;
-
- /* abstract declarator */
- abstract_declarator:
-- '*' m_type_qual_list m_abstract_declarator %prec PPTR
-- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
-+ '*' m_type_qual_bits m_abstract_declarator %prec PPTR
-+ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
- | callconv m_abstract_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
-- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
-+ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- | abstract_direct_declarator
- ;
-
- /* abstract declarator without accepting direct declarator */
- abstract_declarator_no_direct:
-- '*' m_type_qual_list m_any_declarator %prec PPTR
-- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
-+ '*' m_type_qual_bits m_any_declarator %prec PPTR
-+ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
- | callconv m_any_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
-- else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
-+ else if ($$->declspec.type) $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- ;
-
- /* abstract declarator or empty */
-@@ -1024,33 +1022,33 @@ m_abstract_declarator: { $$ = make_declarator(NULL); }
- /* abstract direct declarator */
- abstract_direct_declarator:
- '(' abstract_declarator_no_direct ')' { $$ = $2; }
-- | abstract_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
-- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
-+ | abstract_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
-+ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
- | '(' m_args ')'
- { $$ = make_declarator(NULL);
-- $$->func_type = append_chain_type($$->type, type_new_function($2));
-- $$->type = NULL;
-+ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
-+ $$->declspec.type = NULL;
- }
- | abstract_direct_declarator '(' m_args ')'
- { $$ = $1;
-- $$->func_type = append_chain_type($$->type, type_new_function($3));
-- $$->type = NULL;
-+ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
-+ $$->declspec.type = NULL;
- }
- ;
-
- /* abstract or non-abstract declarator */
- any_declarator:
-- '*' m_type_qual_list m_any_declarator %prec PPTR
-- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
-- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
-+ '*' m_type_qual_bits m_any_declarator %prec PPTR
-+ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
-+ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- | any_direct_declarator
- ;
-
- /* abstract or non-abstract declarator without accepting direct declarator */
- any_declarator_no_direct:
-- '*' m_type_qual_list m_any_declarator %prec PPTR
-- { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
-- | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
-+ '*' m_type_qual_bits m_any_declarator %prec PPTR
-+ { $$ = $3; append_chain_declspec(&$$->declspec, type_new_pointer(pointer_default, NULL), $2); }
-+ | callconv m_any_declarator { $$ = $2; $$->declspec.type->attrs = append_attr($$->declspec.type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
- ;
-
- /* abstract or non-abstract declarator or empty */
-@@ -1064,17 +1062,17 @@ m_any_declarator: { $$ = make_declarator(NULL); }
- any_direct_declarator:
- ident { $$ = make_declarator($1); }
- | '(' any_declarator_no_direct ')' { $$ = $2; }
-- | any_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
-- | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
-+ | any_direct_declarator array { $$ = $1; $$->declspec.type = append_array($$->declspec.type, $2); }
-+ | array { $$ = make_declarator(NULL); $$->declspec.type = append_array($$->declspec.type, $1); }
- | '(' m_args ')'
- { $$ = make_declarator(NULL);
-- $$->func_type = append_chain_type($$->type, type_new_function($2));
-- $$->type = NULL;
-+ $$->func_type = append_chain_type($$->declspec.type, type_new_function($2));
-+ $$->declspec.type = NULL;
- }
- | any_direct_declarator '(' m_args ')'
- { $$ = $1;
-- $$->func_type = append_chain_type($$->type, type_new_function($3));
-- $$->type = NULL;
-+ $$->func_type = append_chain_type($$->declspec.type, type_new_function($3));
-+ $$->declspec.type = NULL;
- }
- ;
-
-@@ -1197,7 +1195,8 @@ static void decl_builtin_basic(const char *name, enum type_basic_type type)
-
- static void decl_builtin_alias(const char *name, type_t *t)
- {
-- reg_type(type_new_alias(t, name), name, NULL, 0);
-+ decl_spec_t ds;
-+ reg_type(type_new_alias(init_declspec(&ds, t), name), name, &global_namespace, 0);
- }
-
- void init_types(void)
-@@ -1208,7 +1207,7 @@ void init_types(void)
- decl_builtin_basic("double", TYPE_BASIC_DOUBLE);
- decl_builtin_basic("error_status_t", TYPE_BASIC_ERROR_STATUS_T);
- decl_builtin_basic("handle_t", TYPE_BASIC_HANDLE);
-- decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_BYTE));
-+ decl_builtin_alias("boolean", type_new_basic(TYPE_BASIC_CHAR));
- }
-
- static str_list_t *append_str(str_list_t *list, char *str)
-@@ -1239,6 +1238,7 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
- LIST_FOR_EACH_ENTRY(attr_existing, list, attr_t, entry)
- if (attr_existing->type == attr->type)
- {
-+ __builtin_trap();
- parser_warning("duplicate attribute %s\n", get_attr_display_name(attr->type));
- /* use the last attribute, like MIDL does */
- list_remove(&attr_existing->entry);
-@@ -1298,53 +1298,73 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
- return new_list;
- }
-
--static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass)
-+static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier)
- {
- decl_spec_t *declspec = left ? left : right;
- if (!declspec)
- {
- declspec = xmalloc(sizeof(*declspec));
- declspec->type = NULL;
-- declspec->attrs = NULL;
- declspec->stgclass = STG_NONE;
-+ declspec->typequalifier = TYPE_QUALIFIER_NONE;
-+ declspec->funcspecifier = FUNCTION_SPECIFIER_NONE;
- }
- declspec->type = type;
- if (left && declspec != left)
- {
-- declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = left->stgclass;
- else if (left->stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
-+
-+ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
-+ declspec->typequalifier = left->typequalifier;
-+ else if (left->typequalifier != TYPE_QUALIFIER_NONE)
-+ error_loc("only one type qualifier can be specified\n");
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
-+ declspec->funcspecifier = left->funcspecifier;
-+ else if (left->funcspecifier != FUNCTION_SPECIFIER_NONE)
-+ error_loc("only one function specifier can be specified\n");
-+
- assert(!left->type);
- free(left);
- }
- if (right && declspec != right)
- {
-- declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = right->stgclass;
- else if (right->stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
-+
-+ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
-+ declspec->typequalifier = right->typequalifier;
-+ else if (right->typequalifier != TYPE_QUALIFIER_NONE)
-+ error_loc("only one type qualifier can be specified\n");
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
-+ declspec->funcspecifier = right->funcspecifier;
-+ else if (right->funcspecifier != FUNCTION_SPECIFIER_NONE)
-+ error_loc("only one function specifier can be specified\n");
-+
- assert(!right->type);
- free(right);
- }
-
-- declspec->attrs = append_attr(declspec->attrs, attr);
- if (declspec->stgclass == STG_NONE)
- declspec->stgclass = stgclass;
- else if (stgclass != STG_NONE)
- error_loc("only one storage class can be specified\n");
-
-- /* apply attributes to type */
-- if (type && declspec->attrs)
-- {
-- attr_list_t *attrs;
-- declspec->type = duptype(type, 1);
-- attrs = map_attrs(type->attrs, NULL);
-- declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
-- declspec->attrs = NULL;
-- }
-+ if (declspec->typequalifier == TYPE_QUALIFIER_NONE)
-+ declspec->typequalifier = typequalifier;
-+ else if (typequalifier != TYPE_QUALIFIER_NONE)
-+ error_loc("only one type qualifier can be specified\n");
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_NONE)
-+ declspec->funcspecifier = funcspecifier;
-+ else if (funcspecifier != FUNCTION_SPECIFIER_NONE)
-+ error_loc("only one function specifier can be specified\n");
-
- return declspec;
- }
-@@ -1430,6 +1450,7 @@ void clear_all_offsets(void)
-
- static void type_function_add_head_arg(type_t *type, var_t *arg)
- {
-+ assert(type_get_type_detect_alias(type) == TYPE_FUNCTION);
- if (!type->details.function->args)
- {
- type->details.function->args = xmalloc( sizeof(*type->details.function->args) );
-@@ -1474,31 +1495,60 @@ static int is_allowed_range_type(const type_t *type)
- static type_t *get_array_or_ptr_ref(type_t *type)
- {
- if (is_ptr(type))
-- return type_pointer_get_ref(type);
-+ return type_pointer_get_ref_type(type);
- else if (is_array(type))
-- return type_array_get_element(type);
-+ return type_array_get_element_type(type);
- return NULL;
- }
-
- static type_t *append_chain_type(type_t *chain, type_t *type)
- {
-- type_t *chain_type;
-+ type_t *chain_type = NULL;
-
- if (!chain)
- return type;
- for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
- ;
-
-+ assert(!type_is_alias(chain_type));
- if (is_ptr(chain_type))
-- chain_type->details.pointer.ref = type;
-+ chain_type->details.pointer.ref.type = type;
- else if (is_array(chain_type))
-- chain_type->details.array.elem = type;
-+ chain_type->details.array.elem.type = type;
- else
- assert(0);
-
- return chain;
- }
-
-+static decl_spec_t *append_chain_declspec(decl_spec_t *chain, type_t *type, enum type_qualifier typequalifier)
-+{
-+ type_t *chain_type = chain->type;
-+ decl_spec_t *chain_declspec = NULL;
-+
-+ if (!chain_type)
-+ {
-+ chain->type = type;
-+ chain->typequalifier = typequalifier;
-+ return chain;
-+ }
-+
-+ for(; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
-+ ;
-+
-+ if (is_ptr(chain_type))
-+ chain_declspec = &chain_type->details.pointer.ref;
-+ else if (is_array(chain_type))
-+ chain_declspec = &chain_type->details.array.elem;
-+ else
-+ assert(NULL);
-+
-+ chain_declspec->type = type;
-+ chain_declspec->typequalifier = typequalifier;
-+
-+ return chain;
-+}
-+
- static warning_list_t *append_warning(warning_list_t *list, int num)
- {
- warning_t *entry;
-@@ -1514,7 +1564,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
- return list;
- }
-
--static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl,
-+static var_t *declare_var(attr_list_t *attrs, decl_spec_t *declspec, const declarator_t *decl,
- int top)
- {
- var_t *v = decl->var;
-@@ -1523,58 +1573,74 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- expr_t *dim;
- type_t **ptype;
- type_t *func_type = decl ? decl->func_type : NULL;
-- type_t *type = decl_spec->type;
-+ type_t *type = declspec->type;
-
-- if (is_attr(type->attrs, ATTR_INLINE))
-- {
-+
-+ if (declspec->funcspecifier == FUNCTION_SPECIFIER_INLINE) {
- if (!func_type)
- error_loc("inline attribute applied to non-function type\n");
- else
- {
-- type_t *t;
-- /* move inline attribute from return type node to function node */
-- for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t))
-- ;
-- t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
-+ v->declspec.funcspecifier = declspec->funcspecifier;
- }
- }
-
-- /* 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;
-+ /* if the var type is a pointerish, we need to move the type qualifier to the pointee's declspec
-+ * unless the pointee already has const type qualifier*/
-+ if (!decl)
-+ {
-+ /* simplest case, no pointers to deal with here */
-+ v->declspec.typequalifier = declspec->typequalifier;
-+ } else if (decl->bits)
-+ {
-+ /* dealing with a bitfield, generate bitfield and copy over typequalifier*/
-+ v->declspec.type = type_new_bitfield(declspec->type, decl->bits);
-+ v->declspec.typequalifier = declspec->typequalifier;
-+ }
-+ else
-+ {
-+ /* here we're dealing with a pointerish type chain, so we need to pull
-+ * the typequalifier off of the declspec and stick them in the type's attr list
-+ */
-+ v->declspec.type = decl->declspec.type;
-+ v->declspec.typequalifier = decl->declspec.typequalifier;
-+ append_chain_declspec(&v->declspec, type, declspec->typequalifier);
-+ }
-+
-+ v->declspec.stgclass = declspec->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);
- if (!ptr_attr && type_is_alias(ptr))
-- ptr = type_alias_get_aliasee(ptr);
-+ ptr = type_alias_get_aliasee_type(ptr);
- else
- break;
- }
- if (is_ptr(ptr))
- {
- if (ptr_attr && ptr_attr != FC_UP &&
-- type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
-+ type_get_type(type_pointer_get_ref_type(ptr)) == TYPE_INTERFACE)
- warning_loc_info(&v->loc_info,
- "%s: pointer attribute applied to interface "
- "pointer type has no effect\n", v->name);
-- if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
-+ if (!ptr_attr && top && type_pointer_get_default_fc(*pt) != FC_RP)
- {
- /* FIXME: this is a horrible hack to cope with the issue that we
- * store an offset to the typeformat string in the type object, but
- * two typeformat strings may be written depending on whether the
- * pointer is a toplevel parameter or not */
-- *pt = duptype(*pt, 1);
-+ *pt = dup_pointer_type(*pt);
- }
- }
- else if (ptr_attr)
-@@ -1585,16 +1651,16 @@ 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);
-
- for (;;)
- {
- if (is_ptr(t))
-- t = type_pointer_get_ref(t);
-+ t = type_pointer_get_ref_type(t);
- else if (is_array(t))
-- t = type_array_get_element(t);
-+ t = type_array_get_element_type(t);
- else
- break;
- }
-@@ -1611,15 +1677,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)
-@@ -1632,7 +1698,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- else
- *ptype = type_new_array((*ptype)->name,
- type_array_get_element(*ptype), FALSE,
-- 0, dim, NULL, 0);
-+ 0, dim, NULL, FC_RP);
- }
- else if (is_ptr(*ptype))
- *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
-@@ -1641,15 +1707,16 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- error_loc("%s: size_is attribute applied to illegal type\n", v->name);
- }
-
-+ assert(!type_is_alias(*ptype));
- if (is_ptr(*ptype))
-- ptype = &(*ptype)->details.pointer.ref;
-+ ptype = &(*ptype)->details.pointer.ref.type;
- else if (is_array(*ptype))
-- ptype = &(*ptype)->details.array.elem;
-+ ptype = &(*ptype)->details.array.elem.type;
- else
- 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)
-@@ -1667,10 +1734,11 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
- error_loc("%s: length_is attribute applied to illegal type\n", v->name);
- }
-
-+ assert(!type_is_alias(*ptype));
- if (is_ptr(*ptype))
-- ptype = &(*ptype)->details.pointer.ref;
-+ ptype = &(*ptype)->details.pointer.ref.type;
- else if (is_array(*ptype))
-- ptype = &(*ptype)->details.array.elem;
-+ ptype = &(*ptype)->details.array.elem.type;
- else
- error_loc("%s: too many expressions in length_is attribute\n", v->name);
- }
-@@ -1681,29 +1749,31 @@ 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;
-+ enum type_qualifier typequalifier = v->declspec.typequalifier;
-+
-+ v->declspec.type = func_type;
-+ v->declspec.typequalifier = TYPE_QUALIFIER_NONE;
-+ for (ft = v->declspec.type; is_ptr(ft); ft = type_pointer_get_ref_type(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;
-+ ft->details.function->retval->declspec.typequalifier = typequalifier;
-+
- /* 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_type(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_type(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);
--
- return v;
- }
-
-@@ -1751,6 +1821,10 @@ var_list_t *append_var(var_list_t *list, var_t *var)
- list_init( list );
- }
- list_add_tail( list, &var->entry );
-+
-+ if (var->declspec.type)
-+ var->declonly = !type_is_defined(var->declspec.type);
-+
- return list;
- }
-
-@@ -1770,11 +1844,11 @@ 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);
-+ v->declonly = TRUE;
- return v;
- }
-
-@@ -1782,10 +1856,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;
- }
-@@ -1805,7 +1878,7 @@ static declarator_t *make_declarator(var_t *var)
- {
- declarator_t *d = xmalloc(sizeof(*d));
- d->var = var ? var : make_var(NULL);
-- d->type = NULL;
-+ init_declspec(&d->declspec, NULL);
- d->func_type = NULL;
- d->bits = NULL;
- return d;
-@@ -1813,7 +1886,15 @@ static declarator_t *make_declarator(var_t *var)
-
- static type_t *make_safearray(type_t *type)
- {
-- return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
-+ decl_spec_t aliasee_ds;
-+ decl_spec_t element_ds;
-+
-+ init_declspec(&element_ds,
-+ type_new_alias(
-+ init_declspec(&aliasee_ds, type),
-+ "SAFEARRAY"));
-+
-+ return type_new_array(NULL, &element_ds, TRUE, 0,
- NULL, NULL, FC_RP);
- }
-
-@@ -1903,15 +1984,16 @@ type_t *reg_type(type_t *type, const char *name, struct namespace *namespace, in
- nt->t = t;
- nt->next = namespace->type_hash[hash];
- namespace->type_hash[hash] = nt;
-- if ((t == tsSTRUCT || t == tsUNION))
-+ if ((t == tsSTRUCT || t == tsUNION || t == tsENUM))
- fix_incomplete_types(type);
- return type;
- }
-
- static int is_incomplete(const type_t *t)
- {
-- return !t->defined &&
-- (type_get_type_detect_alias(t) == TYPE_STRUCT ||
-+ return !type_is_defined(t) &&
-+ (type_get_type_detect_alias(t) == TYPE_ENUM ||
-+ type_get_type_detect_alias(t) == TYPE_STRUCT ||
- type_get_type_detect_alias(t) == TYPE_UNION ||
- type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
- }
-@@ -1919,19 +2001,16 @@ static int is_incomplete(const type_t *t)
- void add_incomplete(type_t *t)
- {
- struct typenode *tn = xmalloc(sizeof *tn);
-+ assert(is_incomplete(t));
- tn->type = t;
- list_add_tail(&incomplete_types, &tn->entry);
- }
-
- static void fix_type(type_t *t)
- {
-- if (type_is_alias(t) && is_incomplete(t)) {
-- type_t *ot = type_alias_get_aliasee(t);
-- fix_type(ot);
-- if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
-- type_get_type_detect_alias(ot) == TYPE_UNION ||
-- type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
-- t->details.structure = ot->details.structure;
-+ if (type_is_alias(t) && is_incomplete(t))
-+ {
-+ type_t *ot = type_alias_get_aliasee_type(t);
- t->defined = ot->defined;
- }
- }
-@@ -1955,7 +2034,7 @@ static void fix_incomplete_types(type_t *complete_type)
- {
- if (type_is_equal(complete_type, tn->type))
- {
-- tn->type->details.structure = complete_type->details.structure;
-+ tn->type->details = complete_type->details;
- list_remove(&tn->entry);
- free(tn);
- }
-@@ -1979,7 +2058,13 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
- type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION)
- {
- if (!type->name)
-+ {
- type->name = gen_name();
-+ /* the generated name will be used and this typedef excluded from the
-+ * built typelib unless the typedef has the 'public' attribute, so add it here */
-+ if (do_typelib && !is_attr(attrs, ATTR_PUBLIC))
-+ attrs = append_attr(attrs, make_attr(ATTR_PUBLIC));
-+ }
-
- /* replace existing attributes when generating a typelib */
- if (do_typelib)
-@@ -2010,7 +2095,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, name->name);
- cur->attrs = attrs;
-
- if (is_incomplete(cur))
-@@ -2178,7 +2263,6 @@ struct allowed_attr allowed_attr[] =
- /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
- /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
- /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
-- /* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
- /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
- /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
- /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },
-@@ -2213,7 +2297,6 @@ struct allowed_attr allowed_attr[] =
- /* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
- /* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
- /* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "in" },
-- /* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
- /* ATTR_INPUTSYNC */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
- /* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, "length_is" },
- /* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
-@@ -2285,10 +2368,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);
-@@ -2493,7 +2576,7 @@ static int is_ptr_guid_type(const type_t *type)
-
- /* second, make sure it is a pointer to something of size sizeof(GUID),
- * i.e. 16 bytes */
-- return (type_memsize(type_pointer_get_ref(type)) == 16);
-+ return (type_memsize(type_pointer_get_ref_type(type)) == 16);
- }
-
- static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
-@@ -2520,7 +2603,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 +2633,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);
-@@ -2647,23 +2730,28 @@ static void check_field_common(const type_t *container_type,
- {
- const type_t *t = type;
- while (is_ptr(t))
-- t = type_pointer_get_ref(t);
-+ t = type_pointer_get_ref_type(t);
- if (is_aliaschain_attr(t, ATTR_RANGE))
- warning_loc_info(&arg->loc_info, "%s: range not verified for a string of ranged types\n", arg->name);
- break;
- }
- case TGT_POINTER:
-- type = type_pointer_get_ref(type);
-+ type = type_pointer_get_ref_type(type);
- more_to_do = TRUE;
- break;
- case TGT_ARRAY:
-- type = type_array_get_element(type);
-+ type = type_array_get_element_type(type);
- more_to_do = TRUE;
- break;
-+ case TGT_ENUM:
-+ type = type_get_real_type(type);
-+ if(!type_is_complete(type))
-+ {
-+ error_loc_info(&arg->loc_info, "undefined type declaration enum %s\n", type->name);
-+ }
- case TGT_USER_TYPE:
- case TGT_IFACE_POINTER:
- case TGT_BASIC:
-- case TGT_ENUM:
- case TGT_RANGE:
- /* nothing to do */
- break;
-@@ -2688,13 +2776,18 @@ static void check_remoting_fields(const var_t *var, type_t *type)
- if (type_is_complete(type))
- fields = type_struct_get_fields(type);
- else
-- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
-+ error_loc_info(&var->loc_info, "undefined type declaration struct %s\n", type->name);
- }
- else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
-- fields = type_union_get_cases(type);
-+ {
-+ if (type_is_complete(type))
-+ fields = type_union_get_cases(type);
-+ else
-+ error_loc_info(&var->loc_info, "undefined type declaration union %s\n", type->name);
-+ }
-
- if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
-- if (field->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 +2796,10 @@ 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 )
-+ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
-+ if (func->declspec.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->declspec.type->details.function->args, const var_t, entry )
- {
-- const type_t *type = arg->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 +2839,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 +2865,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);
- }
- }
-
-@@ -2837,6 +2931,7 @@ static void check_async_uuid(type_t *iface)
- type_t *async_iface;
- type_t *inherit;
-
-+ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
- if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
-
- inherit = iface->details.iface->inherit;
-@@ -2853,7 +2948,8 @@ 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;
-+ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
-+ args = func->declspec.type->details.function->args;
- if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
- {
- if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
-@@ -2863,15 +2959,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));
- }
-
-@@ -2911,6 +3007,7 @@ static void check_statements(const statement_list_t *stmts, int is_inside_librar
- static void check_all_user_types(const statement_list_t *stmts)
- {
- const statement_t *stmt;
-+ const var_t *v;
-
- if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
- {
-@@ -2922,7 +3019,11 @@ 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;
-- check_for_additional_prototype_types(func->type->details.function->args);
-+ assert(type_get_type_detect_alias(func->declspec.type) == TYPE_FUNCTION);
-+ if (func->declspec.type->details.function->args)
-+ LIST_FOR_EACH_ENTRY( v, func->declspec.type->details.function->args, const var_t, entry )
-+ check_for_additional_prototype_types(v->declspec.type);
-+ check_for_additional_prototype_types(type_function_get_rettype(func->declspec.type));
- }
- }
- }
-@@ -2956,6 +3057,10 @@ static statement_t *make_statement_type_decl(type_t *type)
- {
- statement_t *stmt = make_statement(STMT_TYPE);
- stmt->u.type = type;
-+ if (type_is_defined(type))
-+ {
-+ stmt->declonly = FALSE;
-+ }
- return stmt;
- }
-
-@@ -2970,16 +3075,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;
- }
-@@ -3031,6 +3136,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
- declarator_t *decl, *next;
- statement_t *stmt;
- type_list_t **type_list;
-+ int defined = TRUE;
-
- if (!decls) return NULL;
-
-@@ -3042,6 +3148,18 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
- {
- var_t *var = decl->var;
- type_t *type = find_type_or_error(var->name, 0);
-+
-+ /* ensure that all of the types in this typedef statement have been defined
-+ * before setting its declonly flag */
-+ if (type_is_pointerish(type))
-+ {
-+ defined = defined & type_is_defined(type_get_pointer_chain_tail(type));
-+ }
-+ else
-+ {
-+ defined = defined & type_is_defined(type_get_real_type(type));
-+ }
-+
- *type_list = xmalloc(sizeof(type_list_t));
- (*type_list)->type = type;
- (*type_list)->next = NULL;
-@@ -3051,6 +3169,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls)
- free(var);
- }
-
-+ stmt->declonly = !defined;
- return stmt;
- }
-
-@@ -3091,7 +3210,7 @@ void init_loc_info(loc_info_t *i)
-
- static void check_def(const type_t *t)
- {
-- if (t->defined)
-+ if (type_is_defined(t))
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- t->name, t->loc_info.input_name, t->loc_info.line_number);
- }
-diff --git a/mingw-w64-tools/widl/src/parser.yy.c b/mingw-w64-tools/widl/src/parser.yy.c
-index 2aaf3c27..0482aa7e 100644
---- a/mingw-w64-tools/widl/src/parser.yy.c
-+++ b/mingw-w64-tools/widl/src/parser.yy.c
-@@ -1,6 +1,6 @@
--#line 1 "parser.yy.c"
-+#line 2 "parser.yy.c"
-
--#line 3 "parser.yy.c"
-+#line 4 "parser.yy.c"
-
- #define YY_INT_ALIGNED short int
-
-@@ -1041,13 +1041,13 @@ UUID *parse_uuid(const char *u)
- return uuid;
- }
-
--#line 1044 "parser.yy.c"
-+#line 1045 "parser.yy.c"
- /*
- **************************************************************************
- * The flexer starts here
- **************************************************************************
- */
--#line 1050 "parser.yy.c"
-+#line 1051 "parser.yy.c"
-
- #define INITIAL 0
- #define QUOTE 1
-@@ -1281,7 +1281,7 @@ YY_DECL
- {
- #line 132 "parser.l"
-
--#line 1284 "parser.yy.c"
-+#line 1285 "parser.yy.c"
-
- while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
- {
-@@ -1616,7 +1616,7 @@ YY_RULE_SETUP
- #line 239 "parser.l"
- ECHO;
- YY_BREAK
--#line 1619 "parser.yy.c"
-+#line 1620 "parser.yy.c"
-
- case YY_END_OF_BUFFER:
- {
-diff --git a/mingw-w64-tools/widl/src/proxy.c b/mingw-w64-tools/widl/src/proxy.c
-index 87c27be9..36b552be 100644
---- a/mingw-w64-tools/widl/src/proxy.c
-+++ b/mingw-w64-tools/widl/src/proxy.c
-@@ -67,7 +67,7 @@ static void write_stubdesc(int expr_eval_routines)
- print_proxy( "1, /* -error bounds_check flag */\n");
- print_proxy( "0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
- print_proxy( "0,\n");
-- print_proxy( "0x50100a4, /* MIDL Version 5.1.164 */\n");
-+ print_proxy( "0x50200ca, /* MIDL Version 5.2.202 */\n");
- print_proxy( "0,\n");
- print_proxy("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
- print_proxy( "0, /* notify & notify_flag routine table */\n");
-@@ -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_type(arg->declspec.type)) == TYPE_BASIC) continue;
-+ if (type_get_type(type_pointer_get_ref_type(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_function_get_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_declspec_decl_left(proxy, &retval->declspec);
- 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_declspec_decl_left(proxy, &retval->declspec);
- 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_declspec_decl(proxy, &retval->declspec, 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_function_get_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_function_get_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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
-+ fprintf(proxy, ", %s__frame->%s", is_array(arg->declspec.type) && !type_array_is_decl_as_ptr(arg->declspec.type) ? "*" :"" , arg->name);
- }
- fprintf(proxy, ");\n");
- 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_function_get_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 );
-@@ -526,6 +526,7 @@ static int write_proxy_methods(type_t *iface, int skip)
- if (skip || (is_local(func->attrs) && !get_callas_source(iface, func)))
- print_proxy( "0, /* %s::%s */\n", iface->name, get_name(func));
- else if (is_interpreted_func( iface, func ) &&
-+ get_stub_mode() == MODE_Oif &&
- !is_local( func->attrs ) &&
- type_iface_get_inherit(iface))
- print_proxy( "(void *)-1, /* %s::%s */\n", iface->name, get_name(func));
-@@ -613,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 = type_get_details(func->declspec.type)->function->idx;
- if (cname) {
- const statement_t *stmt2;
- STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) {
- const var_t *m = stmt2->u.var;
- if (!strcmp(m->name, cname))
- {
-- idx = m->type->details.function->idx;
-+ idx = type_get_details(m->declspec.type)->function->idx;
- break;
- }
- }
-@@ -738,7 +739,7 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
- print_proxy( "{\n");
- indent++;
- print_proxy( "%s_%s\n",
-- iface->details.iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
-+ type_get_details(iface)->iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
- need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
- indent--;
- print_proxy( "}\n");
-@@ -839,8 +840,8 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
- if (need_proxy(iface))
- {
- write_proxy(iface, proc_offset);
-- if (iface->details.iface->async_iface)
-- write_proxy(iface->details.iface->async_iface, proc_offset);
-+ if (type_get_details(iface)->iface->async_iface)
-+ write_proxy(type_get_details(iface)->iface->async_iface, proc_offset);
- }
- }
- }
-@@ -869,9 +870,9 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
- {
- *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
- (*ifaces)[(*count)++] = iface;
-- if (iface->details.iface->async_iface)
-+ if (type_get_details(iface)->iface->async_iface)
- {
-- iface = iface->details.iface->async_iface;
-+ iface = type_get_details(iface)->iface->async_iface;
- *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
- (*ifaces)[(*count)++] = iface;
- }
-@@ -942,7 +943,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
- write_stubdesc(expr_eval_routines);
-
- print_proxy( "#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32);
-- print_proxy( "#error Currently only Wine and WIN32 are supported.\n");
-+ print_proxy( "#error Invalid build platform for this proxy.\n");
- print_proxy( "#endif\n");
- print_proxy( "\n");
- write_procformatstring(proxy, stmts, need_proxy);
-@@ -1011,7 +1012,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
- table_version = get_stub_mode() == MODE_Oif ? 2 : 1;
- for (i = 0; i < count; i++)
- {
-- if (interfaces[i]->details.iface->async_iface != interfaces[i]) continue;
-+ if (type_get_details(interfaces[i])->iface->async_iface != interfaces[i]) continue;
- if (table_version != 6)
- {
- fprintf(proxy, "static const IID *_AsyncInterfaceTable[] =\n");
-@@ -1053,26 +1054,6 @@ void write_proxies(const statement_list_t *stmts)
- init_proxy(stmts);
- if(!proxy) return;
-
-- if (do_win32 && do_win64)
-- {
-- fprintf(proxy, "\n#ifndef _WIN64\n\n");
-- pointer_size = 4;
-- write_proxy_routines( stmts );
-- fprintf(proxy, "\n#else /* _WIN64 */\n\n");
-- pointer_size = 8;
-- write_proxy_routines( stmts );
-- fprintf(proxy, "\n#endif /* _WIN64 */\n");
-- }
-- else if (do_win32)
-- {
-- pointer_size = 4;
-- write_proxy_routines( stmts );
-- }
-- else if (do_win64)
-- {
-- pointer_size = 8;
-- write_proxy_routines( stmts );
-- }
--
-+ write_proxy_routines( stmts );
- fclose(proxy);
- }
-diff --git a/mingw-w64-tools/widl/src/register.c b/mingw-w64-tools/widl/src/register.c
-index 210fb747..1c369e7c 100644
---- a/mingw-w64-tools/widl/src/register.c
-+++ b/mingw-w64-tools/widl/src/register.c
-@@ -325,7 +325,7 @@ void output_typelib_regscript( const typelib_t *typelib )
- sprintf(resname, "%s\\%d", typelib_name, expr->cval);
- }
- put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
-- lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part );
-+ lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
- put_str( indent, "FLAGS = s '%u'\n", flags );
- put_str( --indent, "}\n" );
- put_str( --indent, "}\n" );
-diff --git a/mingw-w64-tools/widl/src/server.c b/mingw-w64-tools/widl/src/server.c
-index 783ff900..dbed870a 100644
---- a/mingw-w64-tools/widl/src/server.c
-+++ b/mingw-w64-tools/widl/src/server.c
-@@ -55,6 +55,8 @@ 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 );
-+ const decl_spec_t *ret_declspec = type_function_get_retdeclspec(func->declspec.type);
-+ type_t *ret_type = ret_declspec->type;
-
- if (is_interpreted_func( iface, func )) return;
-
-@@ -75,7 +77,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
- indent++;
- write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_FREE);
-
-- if (!is_void(type_function_get_rettype(func->type)))
-+ if (!is_void(ret_type))
- write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_FREE);
-
- if (has_full_pointer)
-@@ -120,7 +122,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_function_get_args(func->declspec.type))
- {
- print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n");
- indent++;
-@@ -154,35 +156,42 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
- assign_stub_out_args(server, indent, func, "__frame->");
-
- /* Call the real server function */
-- print_server("%s%s%s",
-- is_void(type_function_get_rettype(func->type)) ? "" : "__frame->_RetVal = ",
-- prefix_server, get_name(func));
-+ if (is_context_handle(ret_type))
-+ {
-+ print_server("__frame->_RetVal = NDRSContextUnmarshall((char*)0, _pRpcMessage->DataRepresentation);\n");
-+ print_server("*((");
-+ write_declspec_decl(server, ret_declspec, NULL);
-+ fprintf(server, "*)NDRSContextValue(__frame->_RetVal)) = ");
-+ }
-+ else
-+ 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_function_get_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_function_get_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_declspec_decl_left(server, &var->declspec);
- 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");
-@@ -197,7 +206,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
- {
- write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_BUFFERSIZE);
-
-- if (!is_void(type_function_get_rettype(func->type)))
-+ if (!is_void(ret_type))
- write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
-
- print_server("_pRpcMessage->BufferLength = __frame->_StubMsg.BufferLength;\n");
-@@ -216,7 +225,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
- write_remoting_arguments(server, indent, func, "__frame->", PASS_OUT, PHASE_MARSHAL);
-
- /* marshall the return value */
-- if (!is_void(type_function_get_rettype(func->type)))
-+ if (!is_void(ret_type))
- write_remoting_arguments(server, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
-
- indent--;
-@@ -378,7 +387,7 @@ static void write_stubdescriptor(type_t *iface, int expr_eval_routines)
- print_server("1, /* -error bounds_check flag */\n");
- print_server("0x%x, /* Ndr library version */\n", get_stub_mode() == MODE_Oif ? 0x50002 : 0x10001);
- print_server("0,\n");
-- print_server("0x50100a4, /* MIDL Version 5.1.164 */\n");
-+ print_server("0x50200ca, /* MIDL Version 5.2.202 */\n");
- print_server("0,\n");
- print_server("%s,\n", list_empty(&user_type_list) ? "0" : "UserMarshalRoutines");
- print_server("0, /* notify & notify_flag routine table */\n");
-@@ -544,26 +553,6 @@ void write_server(const statement_list_t *stmts)
- if (!server)
- return;
-
-- if (do_win32 && do_win64)
-- {
-- fprintf(server, "#ifndef _WIN64\n\n");
-- pointer_size = 4;
-- write_server_routines( stmts );
-- fprintf(server, "\n#else /* _WIN64 */\n\n");
-- pointer_size = 8;
-- write_server_routines( stmts );
-- fprintf(server, "\n#endif /* _WIN64 */\n");
-- }
-- else if (do_win32)
-- {
-- pointer_size = 4;
-- write_server_routines( stmts );
-- }
-- else if (do_win64)
-- {
-- pointer_size = 8;
-- write_server_routines( stmts );
-- }
--
-+ write_server_routines( stmts );
- fclose(server);
- }
-diff --git a/mingw-w64-tools/widl/src/typegen.c b/mingw-w64-tools/widl/src/typegen.c
-index 27ba60fc..eebb99f0 100644
---- a/mingw-w64-tools/widl/src/typegen.c
-+++ b/mingw-w64-tools/widl/src/typegen.c
-@@ -67,6 +67,7 @@ enum type_context
- TYPE_CONTEXT_PARAM,
- TYPE_CONTEXT_CONTAINER,
- TYPE_CONTEXT_CONTAINER_NO_POINTERS,
-+ TYPE_CONTEXT_RETVAL,
- };
-
- /* parameter flags in Oif mode */
-@@ -84,14 +85,14 @@ static const unsigned short IsSimpleRef = 0x0100;
-
- static unsigned int field_memsize(const type_t *type, unsigned int *offset);
- static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align);
--static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
-+static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- const char *name, unsigned int *typestring_offset);
--static unsigned int write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
--static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
-+static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec, const char *name, unsigned int *tfsoff);
-+static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- const char *name, int write_ptr, unsigned int *tfsoff);
- static const var_t *find_array_or_string_in_struct(const type_t *type);
- static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
-- type_t *type, enum type_context context,
-+ const decl_spec_t *declspec, enum type_context context,
- const char *name, unsigned int *typestring_offset);
- static unsigned int get_required_buffer_size_type( const type_t *type, const char *name,
- const attr_list_t *attrs, int toplevel_param,
-@@ -196,7 +197,7 @@ static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr)
- if (is_attr(t->attrs, attr))
- return get_attrp(t->attrs, attr);
- else if (type_is_alias(t))
-- t = type_alias_get_aliasee(t);
-+ t = type_alias_get_aliasee_type(t);
- else return NULL;
- }
- }
-@@ -266,7 +267,7 @@ unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int t
- if (pointer_type)
- return pointer_type;
-
-- for (t = type; type_is_alias(t); t = type_alias_get_aliasee(t))
-+ for (t = type; type_is_alias(t); t = type_alias_get_aliasee_type(t))
- {
- pointer_type = get_attrv(t->attrs, ATTR_POINTERTYPE);
- if (pointer_type)
-@@ -287,7 +288,7 @@ static unsigned char get_pointer_fc_context( const type_t *type, const attr_list
- int pointer_fc = get_pointer_fc(type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM);
-
- if (pointer_fc == FC_UP && is_attr( attrs, ATTR_OUT ) &&
-- context == TYPE_CONTEXT_PARAM && is_object( current_iface ))
-+ (context == TYPE_CONTEXT_PARAM || context == TYPE_CONTEXT_RETVAL) && is_object( current_iface ))
- pointer_fc = FC_OP;
-
- return pointer_fc;
-@@ -315,7 +316,7 @@ static type_t *get_user_type(const type_t *t, const char **pname)
- }
-
- if (type_is_alias(t))
-- t = type_alias_get_aliasee(t);
-+ t = type_alias_get_aliasee_type(t);
- else
- return NULL;
- }
-@@ -350,10 +351,10 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
- return TGT_RANGE;
- return TGT_ENUM;
- case TYPE_POINTER:
-- if (type_get_type(type_pointer_get_ref(type)) == TYPE_INTERFACE ||
-- (type_get_type(type_pointer_get_ref(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
-+ if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
-+ (type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
- return TGT_IFACE_POINTER;
-- else if (is_aliaschain_attr(type_pointer_get_ref(type), ATTR_CONTEXTHANDLE))
-+ else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
- return TGT_CTXT_HANDLE_POINTER;
- else
- return TGT_POINTER;
-@@ -378,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:
-@@ -404,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);
-@@ -421,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:
-@@ -429,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:
-@@ -442,23 +443,27 @@ static unsigned int get_stack_size( const var_t *var, int *by_value )
- }
-
- static unsigned char get_contexthandle_flags( const type_t *iface, const attr_list_t *attrs,
-- const type_t *type )
-+ const type_t *type, int is_return )
- {
- unsigned char flags = 0;
-+ int is_out;
-
- if (is_attr(iface->attrs, ATTR_STRICTCONTEXTHANDLE)) flags |= NDR_STRICT_CONTEXT_HANDLE;
-
- if (is_ptr(type) &&
- !is_attr( type->attrs, ATTR_CONTEXTHANDLE ) &&
- !is_attr( attrs, ATTR_CONTEXTHANDLE ))
-- flags |= 0x80;
-+ flags |= HANDLE_PARAM_IS_VIA_PTR;
-
-- if (is_attr(attrs, ATTR_IN))
-+ if (is_return) return flags | HANDLE_PARAM_IS_OUT | HANDLE_PARAM_IS_RETURN;
-+
-+ is_out = is_attr(attrs, ATTR_OUT);
-+ if (is_attr(attrs, ATTR_IN) || !is_out)
- {
-- flags |= 0x40;
-- if (!is_attr(attrs, ATTR_OUT)) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
-+ flags |= HANDLE_PARAM_IS_IN;
-+ if (!is_out) flags |= NDR_CONTEXT_HANDLE_CANNOT_BE_NULL;
- }
-- if (is_attr(attrs, ATTR_OUT)) flags |= 0x20;
-+ if (is_out) flags |= HANDLE_PARAM_IS_OUT;
-
- return flags;
- }
-@@ -490,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;
-@@ -505,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_type(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))
-@@ -518,7 +523,7 @@ unsigned char get_struct_fc(const type_t *type)
- if (type_array_has_variance(t))
- has_variance = 1;
-
-- t = type_array_get_element(t);
-+ t = type_array_get_element_type(t);
- typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
- }
-
-@@ -620,7 +625,7 @@ static unsigned char get_array_fc(const type_t *type)
- const expr_t *size_is;
- const type_t *elem_type;
-
-- elem_type = type_array_get_element(type);
-+ elem_type = type_array_get_element_type(type);
- size_is = type_array_get_conformance(type);
-
- if (!size_is)
-@@ -709,14 +714,14 @@ static int type_has_pointers(const type_t *type)
- case TGT_POINTER:
- return TRUE;
- case TGT_ARRAY:
-- return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element(type));
-+ return type_array_is_decl_as_ptr(type) || type_has_pointers(type_array_get_element_type(type));
- case TGT_STRUCT:
- {
- var_list_t *fields = type_struct_get_fields(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;
-@@ -728,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;
-@@ -763,14 +768,14 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
- if (get_pointer_fc(type, attrs, toplevel_param) == FC_FP)
- return TRUE;
- else
-- return type_has_full_pointer(type_array_get_element(type), NULL, FALSE);
-+ return type_has_full_pointer(type_array_get_element_type(type), NULL, FALSE);
- case TGT_STRUCT:
- {
- var_list_t *fields = type_struct_get_fields(type);
- 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;
-@@ -782,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;
-@@ -852,7 +857,7 @@ static const char *get_context_handle_type_name(const type_t *type)
- const type_t *t;
- for (t = type;
- is_ptr(t) || type_is_alias(t);
-- t = type_is_alias(t) ? type_alias_get_aliasee(t) : type_pointer_get_ref(t))
-+ t = type_is_alias(t) ? type_alias_get_aliasee_type(t) : type_pointer_get_ref_type(t))
- if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
- return t->name;
- assert(0);
-@@ -902,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
-+ write_var_init(file, indent, var->declspec.type, var->name, local_var_prefix);
-
- fprintf(file, "\n");
- }
-@@ -975,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 */
-@@ -991,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;
-@@ -1006,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) && type_get_details(var->declspec.type)->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;
- }
-@@ -1031,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_type( var->declspec.type );
-
- if (!is_string_type( var->attrs, ref ))
- buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment );
-@@ -1059,11 +1064,19 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned
- case TGT_UNION:
- case TGT_USER_TYPE:
- case TGT_RANGE:
-- case TGT_ARRAY:
-- *flags |= IsSimpleRef | MustFree;
-+ *flags |= MustFree | IsSimpleRef;
- *typestring_offset = ref->typestring_offset;
- if (!is_in && is_out) server_size = type_memsize( ref );
- break;
-+ case TGT_ARRAY:
-+ *flags |= MustFree;
-+ if (!type_array_is_decl_as_ptr(ref))
-+ {
-+ *flags |= IsSimpleRef;
-+ *typestring_offset = ref->typestring_offset;
-+ }
-+ if (!is_in && is_out) server_size = type_memsize( ref );
-+ break;
- case TGT_STRING:
- case TGT_POINTER:
- case TGT_CTXT_HANDLE:
-@@ -1115,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_function_get_args( func->declspec.type );
-+ var_t *retval = type_function_get_retval( func->declspec.type );
- unsigned char oi2_flags = 0x40; /* HasExtensions */
- unsigned short flags;
- unsigned int stack_size, typestring_offset;
-@@ -1131,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 );
-@@ -1185,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;
-
-@@ -1195,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;
-@@ -1215,10 +1228,12 @@ 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) &&
-+ type_get_details(var->declspec.type)->array.ptr_tfsoff)
-+ {
-+ offset = var->declspec.type->typestring_offset;
-+ }
-
- if (is_return)
- print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
-@@ -1241,8 +1256,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_function_get_args( func->declspec.type );
-+ const type_t *ret_type = type_function_get_rettype( func->declspec.type );
-
- if (type_get_type( ret_type ) == TYPE_BASIC)
- {
-@@ -1264,10 +1279,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;
-@@ -1292,7 +1307,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
- unsigned short num_proc )
- {
- var_t *var;
-- var_list_t *args = type_get_function_args( func->type );
-+ var_list_t *args = type_function_get_args( func->declspec.type );
- unsigned char explicit_fc, implicit_fc;
- unsigned char handle_flags;
- const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc );
-@@ -1323,7 +1338,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++;
-@@ -1351,22 +1366,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 );
-+ 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;
-@@ -1381,7 +1396,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
-
- if (is_attr( func->attrs, ATTR_NOTIFY )) ext_flags |= 0x08; /* HasNotify */
- if (is_attr( func->attrs, ATTR_NOTIFYFLAG )) ext_flags |= 0x10; /* HasNotify2 */
-- if (iface == iface->details.iface->async_iface) oi2_flags |= 0x20;
-+ if (iface == type_get_const_details(iface)->iface->async_iface) oi2_flags |= 0x20;
-
- size = get_function_buffer_size( func, PASS_IN );
- print_file( file, indent, "NdrFcShort(0x%x),\t/* client buffer = %u */\n", size, size );
-@@ -1402,9 +1417,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;
-@@ -1427,15 +1442,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
- {
- print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
- if (is_new_style)
-@@ -1446,7 +1461,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)
- {
-@@ -1475,13 +1490,13 @@ static void for_each_iface(const statement_list_t *stmts,
-
- if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
- {
-- if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE)
-+ if (stmt->type != STMT_TYPE || type_get_type_detect_alias(stmt->u.type) != TYPE_INTERFACE)
- continue;
- iface = stmt->u.type;
- if (!pred(iface)) continue;
- proc(iface, file, indent, offset);
-- if (iface->details.iface->async_iface)
-- proc(iface->details.iface->async_iface, file, indent, offset);
-+ if (type_get_const_details(iface)->iface->async_iface)
-+ proc(type_get_const_details(iface)->iface->async_iface, file, indent, offset);
- }
- }
-
-@@ -1593,7 +1608,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;
- }
-@@ -1656,7 +1671,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
-
- if (type_get_type(cont_type) == TYPE_FUNCTION)
- {
-- var_list_t *args = type_get_function_args( cont_type );
-+ var_list_t *args = type_function_get_args( cont_type );
-
- if (is_object( iface )) offset += pointer_size;
- if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
-@@ -1664,7 +1679,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 );
-@@ -1676,11 +1691,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;
-@@ -1819,7 +1834,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);
-@@ -1841,9 +1856,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;
- }
-@@ -1931,12 +1946,12 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
- {
- if (is_conformant_array(t))
- {
-- type_memsize_and_alignment(type_array_get_element(t), align);
-+ type_memsize_and_alignment(type_array_get_element_type(t), align);
- size = 0;
- }
- else
- size = type_array_get_dim(t) *
-- type_memsize_and_alignment(type_array_get_element(t), align);
-+ type_memsize_and_alignment(type_array_get_element_type(t), align);
- }
- else /* declared as a pointer */
- {
-@@ -2016,8 +2031,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;
-@@ -2025,8 +2040,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;
-@@ -2034,14 +2049,14 @@ 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;
- case TYPE_ARRAY:
- if (!type_array_is_decl_as_ptr(t))
-- return type_buffer_alignment( type_array_get_element(t) );
-+ return type_buffer_alignment( type_array_get_element_type(t) );
- /* else fall through */
- case TYPE_POINTER:
- return 4;
-@@ -2064,12 +2079,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
-+ if (type_has_full_pointer( var->declspec.type, var->attrs, TRUE ))
- return TRUE;
- return FALSE;
- }
-@@ -2114,12 +2129,13 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
- {
- if (context == TYPE_CONTEXT_TOPLEVELPARAM && is_ptr(type) && pointer_type == FC_RP)
- {
-- switch (typegen_detect_type(type_pointer_get_ref(type), NULL, TDT_ALL_TYPES))
-+ switch (typegen_detect_type(type_pointer_get_ref_type(type), NULL, TDT_ALL_TYPES))
- {
- case TGT_STRING:
- case TGT_POINTER:
- case TGT_CTXT_HANDLE:
- case TGT_CTXT_HANDLE_POINTER:
-+ case TGT_ARRAY:
- flags |= FC_ALLOCED_ON_STACK;
- break;
- case TGT_IFACE_POINTER:
-@@ -2134,7 +2150,7 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs
-
- if (is_ptr(type))
- {
-- type_t *ref = type_pointer_get_ref(type);
-+ type_t *ref = type_pointer_get_ref_type(type);
- if(is_declptr(ref) && !is_user_type(ref))
- flags |= FC_POINTER_DEREF;
- }
-@@ -2175,7 +2191,7 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
-
- pointer_fc = get_pointer_fc_context(type, attrs, context);
-
-- ref = type_pointer_get_ref(type);
-+ ref = type_pointer_get_ref_type(type);
- if (type_get_type(ref) == TYPE_ENUM)
- fc = get_enum_fc(ref);
- else
-@@ -2200,22 +2216,23 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
- return 4;
- }
-
--static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff)
-+static void print_start_tfs_comment(FILE *file, const decl_spec_t *ds, unsigned int tfsoff)
- {
- print_file(file, 0, "/* %u (", tfsoff);
-- write_type_decl(file, t, NULL);
-+ write_declspec_decl(file, ds, NULL);
- print_file(file, 0, ") */\n");
- }
-
- static unsigned int write_pointer_tfs(FILE *file, const attr_list_t *attrs,
-- type_t *type, unsigned int ref_offset,
-+ const decl_spec_t *declspec, unsigned int ref_offset,
- enum type_context context,
- unsigned int *typestring_offset)
- {
- unsigned int offset = *typestring_offset;
-- type_t *ref = type_pointer_get_ref(type);
-+ type_t *type = declspec->type;
-+ type_t *ref = type_pointer_get_ref_type(type);
-
-- print_start_tfs_comment(file, type, offset);
-+ print_start_tfs_comment(file, declspec, offset);
- update_tfsoff(type, offset, file);
-
- switch (typegen_detect_type(ref, attrs, TDT_ALL_TYPES))
-@@ -2258,10 +2275,11 @@ static int user_type_has_variable_size(const type_t *t)
- return FALSE;
- }
-
--static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
-+static unsigned int write_user_tfs(FILE *file, const decl_spec_t *declspec, unsigned int *tfsoff)
- {
- unsigned int start, absoff, flags;
- const char *name = NULL;
-+ type_t *type = declspec->type;
- type_t *utype = get_user_type(type, &name);
- unsigned int usize = type_memsize(utype);
- unsigned int ualign = type_buffer_alignment(utype);
-@@ -2279,6 +2297,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
- type_get_type(utype) == TYPE_ENUM)
- {
- unsigned char fc;
-+ decl_spec_t ds;
-
- if (type_get_type(utype) == TYPE_ENUM)
- fc = get_enum_fc(utype);
-@@ -2286,7 +2305,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
- fc = get_basic_fc(utype);
-
- absoff = *tfsoff;
-- print_start_tfs_comment(file, utype, absoff);
-+ print_start_tfs_comment(file, init_declspec(&ds, utype), absoff);
- print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
- print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
- *tfsoff += 2;
-@@ -2294,7 +2313,10 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
- else
- {
- if (!processed(utype))
-- write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff);
-+ {
-+ decl_spec_t ds;
-+ write_embedded_types(file, NULL, init_declspec(&ds, utype), utype->name, TRUE, tfsoff);
-+ }
- absoff = utype->typestring_offset;
- }
-
-@@ -2307,7 +2329,7 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof
-
- start = *tfsoff;
- update_tfsoff(type, start, file);
-- print_start_tfs_comment(file, type, start);
-+ print_start_tfs_comment(file, declspec, start);
- print_file(file, 2, "0x%x,\t/* FC_USER_MARSHAL */\n", FC_USER_MARSHAL);
- print_file(file, 2, "0x%x,\t/* Alignment= %d, Flags= %02x */\n",
- flags | (ualign - 1), ualign - 1, flags);
-@@ -2364,11 +2386,12 @@ static void write_member_type(FILE *file, const type_t *cont,
- static void write_array_element_type(FILE *file, const attr_list_t *attrs, const type_t *type,
- int cont_is_complex, unsigned int *tfsoff)
- {
-- type_t *elem = type_array_get_element(type);
-+ const decl_spec_t *element = type_array_get_element(type);
-+ type_t *elem = element->type;
-
- if (!is_embedded_complex(elem) && is_ptr(elem))
- {
-- type_t *ref = type_pointer_get_ref(elem);
-+ type_t *ref = type_pointer_get_ref_type(elem);
-
- if (processed(ref))
- {
-@@ -2378,7 +2401,7 @@ static void write_array_element_type(FILE *file, const attr_list_t *attrs, const
- }
- if (cont_is_complex && is_string_type(attrs, elem))
- {
-- write_string_tfs(file, NULL, elem, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
-+ write_string_tfs(file, NULL, element, TYPE_CONTEXT_CONTAINER, NULL, tfsoff);
- return;
- }
- if (!is_string_type(NULL, elem) &&
-@@ -2410,7 +2433,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))
- {
-@@ -2433,13 +2456,14 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
- }
-
- static int write_pointer_description_offsets(
-- FILE *file, const attr_list_t *attrs, type_t *type,
-+ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
- unsigned int *typestring_offset)
- {
-+ type_t *type = declspec->type;
- int written = 0;
-
-- if ((is_ptr(type) && type_get_type(type_pointer_get_ref(type)) != TYPE_INTERFACE) ||
-+ if ((is_ptr(type) && type_get_type(type_pointer_get_ref_type(type)) != TYPE_INTERFACE) ||
- (is_array(type) && type_array_is_decl_as_ptr(type)))
- {
- if (offset_in_memory && offset_in_buffer)
-@@ -2464,10 +2488,10 @@ static int write_pointer_description_offsets(
-
- if (is_ptr(type))
- {
-- type_t *ref = type_pointer_get_ref(type);
-+ type_t *ref = type_pointer_get_ref_type(type);
-
- if (is_string_type(attrs, type))
-- write_string_tfs(file, attrs, type, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
-+ write_string_tfs(file, attrs, declspec, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset);
- else if (processed(ref))
- write_nonsimple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER,
- ref->typestring_offset, typestring_offset);
-@@ -2505,13 +2529,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, offset_in_memory, offset_in_buffer,
- typestring_offset);
- }
- }
-@@ -2531,10 +2555,11 @@ static int write_pointer_description_offsets(
- }
-
- static int write_no_repeat_pointer_descriptions(
-- FILE *file, const attr_list_t *attrs, type_t *type,
-+ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
- unsigned int *typestring_offset)
- {
-+ type_t *type = declspec->type;
- int written = 0;
-
- if (is_ptr(type) ||
-@@ -2544,7 +2569,7 @@ static int write_no_repeat_pointer_descriptions(
- print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
- *typestring_offset += 2;
-
-- return write_pointer_description_offsets(file, attrs, type,
-+ return write_pointer_description_offsets(file, attrs, declspec,
- offset_in_memory, offset_in_buffer, typestring_offset);
- }
-
-@@ -2557,13 +2582,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,
- offset_in_memory, offset_in_buffer, typestring_offset);
- }
- }
-@@ -2582,10 +2607,11 @@ static int write_no_repeat_pointer_descriptions(
- /* Note: if file is NULL return value is number of pointers to write, else
- * it is the number of type format characters written */
- static int write_fixed_array_pointer_descriptions(
-- FILE *file, const attr_list_t *attrs, type_t *type,
-+ FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- unsigned int *offset_in_memory, unsigned int *offset_in_buffer,
- unsigned int *typestring_offset)
- {
-+ type_t *type = declspec->type;
- int pointer_count = 0;
-
- if (type_get_type(type) == TYPE_ARRAY &&
-@@ -2602,7 +2628,7 @@ static int write_fixed_array_pointer_descriptions(
- unsigned int offset_of_array_pointer_mem = 0;
- unsigned int offset_of_array_pointer_buf = 0;
-
-- increment_size = type_memsize(type_array_get_element(type));
-+ increment_size = type_memsize(type_array_get_element_type(type));
-
- print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", FC_FIXED_REPEAT);
- print_file(file, 2, "0x%02x, /* FC_PAD */\n", FC_PAD);
-@@ -2613,7 +2639,7 @@ static int write_fixed_array_pointer_descriptions(
- *typestring_offset += 10;
-
- pointer_count = write_pointer_description_offsets(
-- file, attrs, type, &offset_of_array_pointer_mem,
-+ file, attrs, declspec, &offset_of_array_pointer_mem,
- &offset_of_array_pointer_buf, typestring_offset);
- }
- }
-@@ -2626,13 +2652,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, offset_in_memory, offset_in_buffer,
- typestring_offset);
- }
- }
-@@ -2673,7 +2699,7 @@ static int write_conformant_array_pointer_descriptions(
- unsigned int offset_of_array_pointer_mem = offset_in_memory;
- unsigned int offset_of_array_pointer_buf = offset_in_memory;
-
-- increment_size = type_memsize(type_array_get_element(type));
-+ increment_size = type_memsize(type_array_get_element_type(type));
-
- if (increment_size > USHRT_MAX)
- error("array size of %u bytes is too large\n", increment_size);
-@@ -2715,7 +2741,7 @@ static int write_varying_array_pointer_descriptions(
- {
- unsigned int increment_size;
-
-- increment_size = type_memsize(type_array_get_element(type));
-+ increment_size = type_memsize(type_array_get_element_type(type));
-
- if (increment_size > USHRT_MAX)
- error("array size of %u bytes is too large\n", increment_size);
-@@ -2741,20 +2767,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);
- }
- }
-@@ -2773,9 +2799,10 @@ static int write_varying_array_pointer_descriptions(
- return pointer_count;
- }
-
--static void write_pointer_description(FILE *file, const attr_list_t *attrs, type_t *type,
-+static void write_pointer_description(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- unsigned int *typestring_offset)
- {
-+ type_t *type = declspec->type;
- unsigned int offset_in_buffer;
- unsigned int offset_in_memory;
-
-@@ -2786,7 +2813,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
- offset_in_memory = 0;
- offset_in_buffer = 0;
- write_no_repeat_pointer_descriptions(
-- file, NULL, type,
-+ file, NULL, declspec,
- &offset_in_memory, &offset_in_buffer, typestring_offset);
- }
-
-@@ -2794,7 +2821,7 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
- offset_in_memory = 0;
- offset_in_buffer = 0;
- write_fixed_array_pointer_descriptions(
-- file, NULL, type,
-+ file, NULL, declspec,
- &offset_in_memory, &offset_in_buffer, typestring_offset);
-
- /* pass 3: search for pointers in conformant only arrays (but don't descend
-@@ -2806,7 +2833,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);
- }
-@@ -2820,9 +2847,10 @@ static void write_pointer_description(FILE *file, const attr_list_t *attrs, type
- }
-
- static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
-- type_t *type, enum type_context context,
-+ const decl_spec_t *declspec, enum type_context context,
- const char *name, unsigned int *typestring_offset)
- {
-+ type_t *type = declspec->type;
- unsigned int start_offset;
- unsigned char rtype;
- type_t *elem_type;
-@@ -2836,7 +2864,7 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
- int pointer_type = get_pointer_fc_context(type, attrs, context);
- if (!pointer_type)
- pointer_type = FC_RP;
-- print_start_tfs_comment(file, type, *typestring_offset);
-+ print_start_tfs_comment(file, declspec, *typestring_offset);
- print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
- pointer_type, flag, string_of_type(pointer_type),
- flag ? " [simple_pointer]" : "");
-@@ -2850,12 +2878,12 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
- }
-
- if (is_array(type))
-- elem_type = type_array_get_element(type);
-+ elem_type = type_array_get_element_type(type);
- else
-- elem_type = type_pointer_get_ref(type);
-+ elem_type = type_pointer_get_ref_type(type);
-
- if (type_get_type(elem_type) == TYPE_POINTER && is_array(type))
-- return write_array_tfs(file, attrs, type, name, typestring_offset);
-+ return write_array_tfs(file, attrs, declspec, name, typestring_offset);
-
- if (type_get_type(elem_type) != TYPE_BASIC)
- {
-@@ -2929,34 +2957,31 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs,
- }
- }
-
--static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
-+static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- const char *name, unsigned int *typestring_offset)
- {
-+ type_t *type = declspec->type;
- const expr_t *length_is = type_array_get_variance(type);
- const expr_t *size_is = type_array_get_conformance(type);
- unsigned int align;
- unsigned int size;
- unsigned int start_offset;
- unsigned char fc;
-- int pointer_type = get_attrv(attrs, ATTR_POINTERTYPE);
- unsigned int baseoff
- = !type_array_is_decl_as_ptr(type) && current_structure
- ? type_memsize(current_structure)
- : 0;
-
-- if (!pointer_type)
-- pointer_type = FC_RP;
--
-- if (!is_string_type(attrs, type_array_get_element(type)))
-+ if (!is_string_type(attrs, type_array_get_element_type(type)))
- write_embedded_types(file, attrs, type_array_get_element(type), name, FALSE, typestring_offset);
-
-- size = type_memsize(is_conformant_array(type) ? type_array_get_element(type) : type);
-- align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element(type) : type);
-+ size = type_memsize(is_conformant_array(type) ? type_array_get_element_type(type) : type);
-+ align = type_buffer_alignment(is_conformant_array(type) ? type_array_get_element_type(type) : type);
- fc = get_array_fc(type);
-
- start_offset = *typestring_offset;
- update_tfsoff(type, start_offset, file);
-- print_start_tfs_comment(file, type, start_offset);
-+ print_start_tfs_comment(file, declspec, start_offset);
- print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
- print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
- *typestring_offset += 2;
-@@ -2982,7 +3007,7 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
-
- if (fc == FC_SMVARRAY || fc == FC_LGVARRAY)
- {
-- unsigned int elsize = type_memsize(type_array_get_element(type));
-+ unsigned int elsize = type_memsize(type_array_get_element_type(type));
- unsigned int dim = type_array_get_dim(type);
-
- if (fc == FC_LGVARRAY)
-@@ -3005,13 +3030,13 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
- += write_conf_or_var_desc(file, current_structure, baseoff,
- type, length_is);
-
-- if (type_has_pointers(type_array_get_element(type)) &&
-+ if (type_has_pointers(type_array_get_element_type(type)) &&
- (type_array_is_decl_as_ptr(type) || !current_structure))
- {
- print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
- print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
- *typestring_offset += 2;
-- write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, type, typestring_offset);
-+ write_pointer_description(file, is_string_type(attrs, type) ? attrs : NULL, declspec, typestring_offset);
- print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
- *typestring_offset += 1;
- }
-@@ -3048,7 +3073,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;
-@@ -3071,7 +3096,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);
-@@ -3100,7 +3125,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;
- }
-@@ -3118,9 +3143,10 @@ static void write_struct_members(FILE *file, const type_t *type,
- write_end(file, typestring_offset);
- }
-
--static unsigned int write_struct_tfs(FILE *file, type_t *type,
-+static unsigned int write_struct_tfs(FILE *file, const decl_spec_t *declspec,
- const char *name, unsigned int *tfsoff)
- {
-+ type_t *type = declspec->type;
- const type_t *save_current_structure = current_structure;
- unsigned int total_size;
- const var_t *array;
-@@ -3143,15 +3169,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, 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_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, array->name, tfsoff);
- }
-
- corroff = *tfsoff;
-@@ -3159,7 +3185,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
-
- start_offset = *tfsoff;
- update_tfsoff(type, start_offset, file);
-- print_start_tfs_comment(file, type, start_offset);
-+ print_start_tfs_comment(file, declspec, start_offset);
- print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
- print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
- print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)total_size, total_size);
-@@ -3167,7 +3193,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);
-@@ -3198,7 +3224,7 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
- print_file(file, 2, "0x%x,\t/* FC_PP */\n", FC_PP);
- print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD);
- *tfsoff += 2;
-- write_pointer_description(file, NULL, type, tfsoff);
-+ write_pointer_description(file, NULL, declspec, tfsoff);
- print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END);
- *tfsoff += 1;
- }
-@@ -3213,15 +3239,16 @@ 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;
-+ const decl_spec_t *fds = &f->declspec;
-+ type_t *ft = fds->type;
- switch (typegen_detect_type(ft, f->attrs, TDT_IGNORE_STRINGS))
- {
- case TGT_POINTER:
- if (is_string_type(f->attrs, ft))
-- write_string_tfs(file, f->attrs, ft, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
-+ write_string_tfs(file, f->attrs, fds, TYPE_CONTEXT_CONTAINER, f->name, tfsoff);
- else
-- write_pointer_tfs(file, f->attrs, ft,
-- type_pointer_get_ref(ft)->typestring_offset,
-+ write_pointer_tfs(file, f->attrs, fds,
-+ type_pointer_get_ref_type(ft)->typestring_offset,
- TYPE_CONTEXT_CONTAINER, tfsoff);
- break;
- case TGT_ARRAY:
-@@ -3283,8 +3310,9 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
- }
-
- static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
-- type_t *type, unsigned int *tfsoff)
-+ const decl_spec_t *declspec, unsigned int *tfsoff)
- {
-+ type_t* type = declspec->type;
- unsigned int start_offset;
- unsigned int size;
- var_list_t *fields;
-@@ -3309,17 +3337,17 @@ 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, f->name, TRUE, tfsoff);
- }
-
- start_offset = *tfsoff;
- update_tfsoff(type, start_offset, file);
-- print_start_tfs_comment(file, type, start_offset);
-+ print_start_tfs_comment(file, declspec, start_offset);
- 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;
-
-@@ -3351,8 +3379,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);
-@@ -3407,7 +3435,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;
-@@ -3448,16 +3476,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
- return start_offset;
- }
-
--static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
-+static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- unsigned int *typeformat_offset)
- {
- unsigned int i;
-+ type_t *type = declspec->type;
- unsigned int start_offset = *typeformat_offset;
- expr_t *iid = get_attrp(attrs, ATTR_IIDIS);
-
- if (!iid && processed(type)) return type->typestring_offset;
-
-- print_start_tfs_comment(file, type, start_offset);
-+ print_start_tfs_comment(file, declspec, start_offset);
- update_tfsoff(type, start_offset, file);
-
- if (iid)
-@@ -3469,7 +3498,7 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
- }
- else
- {
-- const type_t *base = is_ptr(type) ? type_pointer_get_ref(type) : type;
-+ const type_t *base = is_ptr(type) ? type_pointer_get_ref_type(type) : type;
- const UUID *uuid = get_attrp(base->attrs, ATTR_UUID);
-
- if (! uuid)
-@@ -3493,18 +3522,19 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
-
- static unsigned int write_contexthandle_tfs(FILE *file,
- const attr_list_t *attrs,
-- type_t *type,
-- int toplevel_param,
-+ const decl_spec_t *declspec,
-+ enum type_context context,
- unsigned int *typeformat_offset)
- {
-+ type_t *type = declspec->type;
- unsigned int start_offset = *typeformat_offset;
-- unsigned char flags = get_contexthandle_flags( current_iface, attrs, type );
-+ unsigned char flags = get_contexthandle_flags( current_iface, attrs, type, context == TYPE_CONTEXT_RETVAL );
-
-- print_start_tfs_comment(file, type, start_offset);
-+ print_start_tfs_comment(file, declspec, start_offset);
-
- if (flags & 0x80) /* via ptr */
- {
-- int pointer_type = get_pointer_fc( type, attrs, toplevel_param );
-+ int pointer_type = get_pointer_fc( type, attrs, context == TYPE_CONTEXT_TOPLEVELPARAM );
- if (!pointer_type) pointer_type = FC_RP;
- *typeformat_offset += 4;
- print_file(file, 2,"0x%x, 0x0,\t/* %s */\n", pointer_type, string_of_type(pointer_type) );
-@@ -3514,8 +3544,7 @@ static unsigned int write_contexthandle_tfs(FILE *file,
-
- print_file(file, 2, "0x%02x,\t/* FC_BIND_CONTEXT */\n", FC_BIND_CONTEXT);
- print_file(file, 2, "0x%x,\t/* Context flags: ", flags);
-- /* return and can't be null values overlap */
-- if (((flags & 0x21) != 0x21) && (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL))
-+ if (flags & NDR_CONTEXT_HANDLE_CANNOT_BE_NULL)
- print_file(file, 0, "can't be null, ");
- if (flags & NDR_CONTEXT_HANDLE_SERIALIZE)
- print_file(file, 0, "serialize, ");
-@@ -3523,13 +3552,13 @@ static unsigned int write_contexthandle_tfs(FILE *file,
- print_file(file, 0, "no serialize, ");
- if (flags & NDR_STRICT_CONTEXT_HANDLE)
- print_file(file, 0, "strict, ");
-- if ((flags & 0x21) == 0x20)
-- print_file(file, 0, "out, ");
-- if ((flags & 0x21) == 0x21)
-+ if (flags & HANDLE_PARAM_IS_RETURN)
- print_file(file, 0, "return, ");
-- if (flags & 0x40)
-+ if (flags & HANDLE_PARAM_IS_OUT)
-+ print_file(file, 0, "out, ");
-+ if (flags & HANDLE_PARAM_IS_IN)
- print_file(file, 0, "in, ");
-- if (flags & 0x80)
-+ if (flags & HANDLE_PARAM_IS_VIA_PTR)
- print_file(file, 0, "via ptr, ");
- print_file(file, 0, "*/\n");
- print_file(file, 2, "0x%x,\t/* rundown routine */\n", get_context_handle_offset( type ));
-@@ -3568,24 +3597,23 @@ static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs,
- return start_offset;
- }
-
--static unsigned int write_type_tfs(FILE *file, int indent,
-- const attr_list_t *attrs, type_t *type,
-- const char *name,
-+static unsigned int write_type_tfs(FILE *file, const attr_list_t *attrs,
-+ const decl_spec_t *declspec, const char *name,
- enum type_context context,
- unsigned int *typeformat_offset)
- {
- unsigned int offset;
-+ type_t *type = declspec->type;
-
- switch (typegen_detect_type(type, attrs, TDT_ALL_TYPES))
- {
- case TGT_CTXT_HANDLE:
- case TGT_CTXT_HANDLE_POINTER:
-- return write_contexthandle_tfs(file, attrs, type,
-- context == TYPE_CONTEXT_TOPLEVELPARAM, typeformat_offset);
-+ return write_contexthandle_tfs(file, attrs, declspec, context, typeformat_offset);
- case TGT_USER_TYPE:
-- return write_user_tfs(file, type, typeformat_offset);
-+ return write_user_tfs(file, declspec, typeformat_offset);
- case TGT_STRING:
-- return write_string_tfs(file, attrs, type, context, name, typeformat_offset);
-+ return write_string_tfs(file, attrs, declspec, context, name, typeformat_offset);
- case TGT_ARRAY:
- {
- unsigned int off;
-@@ -3593,15 +3621,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
- if ((context != TYPE_CONTEXT_CONTAINER &&
- context != TYPE_CONTEXT_CONTAINER_NO_POINTERS) ||
- !is_conformant_array(type) || type_array_is_decl_as_ptr(type))
-- off = write_array_tfs(file, attrs, type, name, typeformat_offset);
-+ off = write_array_tfs(file, attrs, declspec, name, typeformat_offset);
- else
- off = 0;
- if (context != TYPE_CONTEXT_CONTAINER &&
- context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
- {
- int ptr_type;
-- ptr_type = get_pointer_fc(type, attrs,
-- context == TYPE_CONTEXT_TOPLEVELPARAM);
-+ ptr_type = get_pointer_fc_context(type, attrs, context);
- if (ptr_type != FC_RP || type_array_is_decl_as_ptr(type))
- {
- unsigned int absoff = type->typestring_offset;
-@@ -3615,14 +3642,14 @@ static unsigned int write_type_tfs(FILE *file, int indent,
- if (ptr_type != FC_RP) update_tfsoff( type, off, file );
- *typeformat_offset += 4;
- }
-- type->details.array.ptr_tfsoff = off;
-+ type_get_details(type)->array.ptr_tfsoff = off;
- }
- return off;
- }
- case TGT_STRUCT:
-- return write_struct_tfs(file, type, name, typeformat_offset);
-+ return write_struct_tfs(file, declspec, name, typeformat_offset);
- case TGT_UNION:
-- return write_union_tfs(file, attrs, type, typeformat_offset);
-+ return write_union_tfs(file, attrs, declspec, typeformat_offset);
- case TGT_ENUM:
- case TGT_BASIC:
- /* nothing to do */
-@@ -3635,11 +3662,11 @@ static unsigned int write_type_tfs(FILE *file, int indent,
- return write_range_tfs(file, attrs, type, range_list, typeformat_offset);
- }
- case TGT_IFACE_POINTER:
-- return write_ip_tfs(file, attrs, type, typeformat_offset);
-+ return write_ip_tfs(file, attrs, declspec, typeformat_offset);
- case TGT_POINTER:
- {
- enum type_context ref_context;
-- type_t *ref = type_pointer_get_ref(type);
-+ const decl_spec_t *ref = type_pointer_get_ref(type);
-
- if (context == TYPE_CONTEXT_TOPLEVELPARAM)
- ref_context = TYPE_CONTEXT_PARAM;
-@@ -3648,22 +3675,22 @@ static unsigned int write_type_tfs(FILE *file, int indent,
- else
- ref_context = context;
-
-- if (is_string_type(attrs, ref))
-+ if (is_string_type(attrs, ref->type))
- {
- if (context != TYPE_CONTEXT_CONTAINER_NO_POINTERS)
-- write_pointer_tfs(file, attrs, type, *typeformat_offset + 4, context, typeformat_offset);
-+ write_pointer_tfs(file, attrs, declspec, *typeformat_offset + 4, context, typeformat_offset);
-
-- offset = write_type_tfs(file, indent, attrs, ref, name, ref_context, typeformat_offset);
-+ offset = write_type_tfs(file, attrs, ref, name, ref_context, typeformat_offset);
- if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
- return 0;
- return offset;
- }
-
-- offset = write_type_tfs( file, indent, attrs, type_pointer_get_ref(type), name,
-+ offset = write_type_tfs( file, attrs, type_pointer_get_ref(type), name,
- ref_context, typeformat_offset);
- if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS)
- return 0;
-- return write_pointer_tfs(file, attrs, type, offset, context, typeformat_offset);
-+ return write_pointer_tfs(file, attrs, declspec, offset, context, typeformat_offset);
- }
- case TGT_INVALID:
- break;
-@@ -3672,10 +3699,10 @@ static unsigned int write_type_tfs(FILE *file, int indent,
- return 0;
- }
-
--static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
-+static int write_embedded_types(FILE *file, const attr_list_t *attrs, const decl_spec_t *declspec,
- const char *name, int write_ptr, unsigned int *tfsoff)
- {
-- return write_type_tfs(file, 2, attrs, type, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
-+ return write_type_tfs(file, attrs, declspec, name, write_ptr ? TYPE_CONTEXT_CONTAINER : TYPE_CONTEXT_CONTAINER_NO_POINTERS, tfsoff);
- }
-
- static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned int *offset)
-@@ -3693,21 +3720,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, 2, func->attrs, var->type, func->name,
-- TYPE_CONTEXT_PARAM, offset);
-+ 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, 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, 2, var->attrs, var->type, var->name,
-+ if (type_function_get_args(func->declspec.type))
-+ LIST_FOR_EACH_ENTRY( var, type_function_get_args(func->declspec.type), var_t, entry )
-+ var->typestring_offset = write_type_tfs( file, var->attrs, &var->declspec, var->name,
- TYPE_CONTEXT_TOPLEVELPARAM, offset );
- break;
-
-@@ -3719,9 +3746,12 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in
- {
- if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
- || is_attr(type_entry->type->attrs, ATTR_DECODE))
-- type_entry->type->typestring_offset = write_type_tfs( file, 2,
-- type_entry->type->attrs, type_entry->type, type_entry->type->name,
-+ {
-+ decl_spec_t ds;
-+ type_entry->type->typestring_offset = write_type_tfs( file,
-+ type_entry->type->attrs, init_declspec(&ds, type_entry->type), type_entry->type->name,
- TYPE_CONTEXT_CONTAINER, offset);
-+ }
- }
- break;
- }
-@@ -3842,7 +3872,7 @@ static unsigned int get_required_buffer_size_type(
- case TGT_POINTER:
- {
- unsigned int size, align;
-- const type_t *ref = type_pointer_get_ref(type);
-+ const type_t *ref = type_pointer_get_ref_type(type);
- if (is_string_type( attrs, ref )) break;
- if (!(size = get_required_buffer_size_type( ref, name, NULL, FALSE, &align ))) break;
- if (get_pointer_fc(type, attrs, toplevel_param) != FC_RP)
-@@ -3862,7 +3892,7 @@ static unsigned int get_required_buffer_size_type(
- case FC_SMFARRAY:
- case FC_LGFARRAY:
- return type_array_get_dim(type) *
-- get_required_buffer_size_type(type_array_get_element(type), name,
-+ get_required_buffer_size_type(type_array_get_element_type(type), name,
- NULL, FALSE, alignment);
- }
- }
-@@ -3893,8 +3923,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;
-@@ -3905,19 +3935,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_function_get_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_function_get_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;
- }
-@@ -3953,9 +3983,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) ? "," : ");");
-@@ -3968,7 +3998,8 @@ 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;
-+ const decl_spec_t *declspec = &var->declspec;
-+ type_t *type = declspec->type;
- unsigned int alignment = 0;
-
- /* no work to do for other phases, buffer sizing is done elsewhere */
-@@ -3999,8 +4030,8 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
- }
- else
- {
-- const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type;
-- switch (get_basic_fc(ref))
-+ const decl_spec_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : declspec;
-+ switch (get_basic_fc(ref->type))
- {
- case FC_BYTE:
- case FC_CHAR:
-@@ -4037,7 +4068,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
-
- default:
- error("print_phase_basetype: Unsupported type: %s (0x%02x, ptr_level: 0)\n",
-- var->name, get_basic_fc(ref));
-+ var->name, get_basic_fc(ref->type));
- }
-
- if (phase == PHASE_MARSHAL && alignment > 1)
-@@ -4048,7 +4079,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
- if (phase == PHASE_MARSHAL)
- {
- print_file(file, indent, "*(");
-- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
-+ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
- if (is_ptr(type))
- fprintf(file, " *)__frame->_StubMsg.Buffer = *");
- else
-@@ -4059,7 +4090,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
- else if (phase == PHASE_UNMARSHAL)
- {
- print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof(");
-- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
-+ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
- fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n");
- print_file(file, indent, "{\n");
- print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n");
-@@ -4071,12 +4102,12 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
- fprintf(file, " = (");
- else
- fprintf(file, " = *(");
-- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
-+ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
- fprintf(file, " *)__frame->_StubMsg.Buffer;\n");
- }
-
- print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof(");
-- write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL);
-+ write_declspec_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : declspec, NULL);
- fprintf(file, ");\n");
- }
- }
-@@ -4092,7 +4123,7 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
- {
- expr_t *x = NULL;
-
-- for ( ; is_array(t); t = type_array_get_element(t))
-+ for ( ; is_array(t); t = type_array_get_element_type(t))
- if (type_array_has_conformance(t) &&
- type_array_get_conformance(t)->type != EXPR_VOID)
- {
-@@ -4110,7 +4141,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 (;;)
- {
-@@ -4162,7 +4193,7 @@ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local
- break;
- }
- case TGT_POINTER:
-- type = type_pointer_get_ref(type);
-+ type = type_pointer_get_ref_type(type);
- continue;
- case TGT_INVALID:
- case TGT_USER_TYPE:
-@@ -4184,7 +4215,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))
-@@ -4237,19 +4268,20 @@ 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);
- }
- }
- else if (phase == PHASE_UNMARSHAL)
- {
-- if (pass == PASS_OUT)
-+ if (pass == PASS_OUT || pass == PASS_RETURN)
- {
- if (!in_attr)
- print_file(file, indent, "*%s%s = 0;\n", local_var_prefix, var->name);
- print_file(file, indent, "NdrClientContextUnmarshall(\n");
- print_file(file, indent + 1, "&__frame->_StubMsg,\n");
-- print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s,\n", local_var_prefix, var->name);
-+ print_file(file, indent + 1, "(NDR_CCONTEXT *)%s%s%s,\n",
-+ pass == PASS_RETURN ? "&" : "", local_var_prefix, var->name);
- print_file(file, indent + 1, "__frame->_Handle);\n");
- }
- else
-@@ -4343,10 +4375,10 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
- ((tc == FC_SMVARRAY || tc == FC_LGVARRAY) && in_attr) ||
- (tc == FC_CARRAY && !in_attr))
- {
-- if (type_array_is_decl_as_ptr(type) && type->details.array.ptr_tfsoff)
-+ if (type_array_is_decl_as_ptr(type) && type_get_const_details(type)->array.ptr_tfsoff)
- {
- print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var,
-- type->details.array.ptr_tfsoff);
-+ type_get_const_details(type)->array.ptr_tfsoff);
- break;
- }
- print_phase_function(file, indent, array_type, local_var_prefix, phase, var, start_offset);
-@@ -4380,9 +4412,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_declspec_decl(file, &var->declspec, NULL);
- fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name);
-- write_type_decl(file, var->type, NULL);
-+ write_declspec_decl(file, &var->declspec, 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");
-@@ -4428,7 +4460,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
- }
- case TGT_POINTER:
- {
-- const type_t *ref = type_pointer_get_ref(type);
-+ const type_t *ref = type_pointer_get_ref_type(type);
- if (pointer_type == FC_RP) switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
- {
- case TGT_BASIC:
-@@ -4549,14 +4581,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
- write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var );
- }
- }
-@@ -4597,57 +4629,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))
- {
-- print_file(file, indent, "%s", "");
-- write_type_decl(file, var->type, var->name);
-- fprintf(file, ";\n");
-+ if (is_context_handle(var->declspec.type))
-+ print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
-+ else
-+ {
-+ print_file(file, indent, "%s", "");
-+ write_declspec_decl(file, &var->declspec, var->name);
-+ fprintf(file, ";\n");
-+ }
- }
-
-- if (!type_get_function_args(func->type))
-+ if (!type_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
- {
- in_attr = is_attr(var->attrs, ATTR_IN);
- out_attr = is_attr(var->attrs, ATTR_OUT);
- 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;
-+ const decl_spec_t *declspec_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))
-+ declspec_to_print = &var->declspec;
- else
-- type_to_print = type_pointer_get_ref(var->type);
-+ declspec_to_print = type_pointer_get_ref(var->declspec.type);
- sprintf(name, "_W%u", i++);
-- write_type_decl(file, type_to_print, name);
-+ write_declspec_decl(file, declspec_to_print, name);
- fprintf(file, ";\n");
- }
-
- print_file(file, indent, "%s", "");
-- write_type_decl_left(file, var->type);
-+ write_declspec_decl_left(file, &var->declspec);
- 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);
- }
- }
-@@ -4661,10 +4698,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_function_get_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_function_get_args(func->declspec.type), const var_t, entry )
- {
- in_attr = is_attr(var->attrs, ATTR_IN);
- out_attr = is_attr(var->attrs, ATTR_OUT);
-@@ -4675,7 +4712,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");
-@@ -4684,15 +4721,15 @@ 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))
-+ type = type_array_get_element_type(type))
- {
- write_expr(file, type_array_get_conformance(type), TRUE,
- TRUE, NULL, NULL, local_var_prefix);
-@@ -4702,9 +4739,9 @@ 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))
-+ type = type_array_get_element_type(type))
- {
- write_expr(file, type_array_get_conformance(type), TRUE,
- TRUE, NULL, NULL, local_var_prefix);
-@@ -4718,7 +4755,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_type(var->declspec.type);
- switch (typegen_detect_type(ref, var->attrs, TDT_IGNORE_STRINGS))
- {
- case TGT_BASIC:
-@@ -4738,7 +4775,7 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
- print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i);
- break;
- }
-- ref = type_array_get_element(ref);
-+ ref = type_array_get_element_type(ref);
- /* fall through */
- case TGT_STRUCT:
- case TGT_UNION:
-@@ -4771,14 +4808,14 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun
- const char *var_decl, int add_retval )
- {
- var_t *retval = type_function_get_retval( func );
-- const var_list_t *args = type_get_function_args( func );
-+ const var_list_t *args = type_function_get_args( func );
- const var_t *arg;
- int needs_packing;
- unsigned int align = 0;
-
- 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);
-
-@@ -4790,26 +4827,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_declspec_left( file, &arg->declspec, 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_declspec_decl( file, &retval->declspec, 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 );
-@@ -4821,7 +4858,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_function_get_args( func->declspec.type );
- const var_t *var;
-
- if (!args) return;
-@@ -4854,10 +4891,11 @@ int write_expr_eval_routines(FILE *file, const char *iface)
- }
- else
- {
-+ decl_spec_t declspec;
- print_file(file, 1, "%s", "");
-- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
-+ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
- fprintf(file, " *%s = (", var_name);
-- write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE);
-+ write_declspec_left(file, init_declspec(&declspec, (type_t*)eval->cont_type), NAME_DEFAULT, TRUE);
- fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
- }
- print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
-@@ -4951,9 +4989,10 @@ 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 );
-+ const decl_spec_t *retdeclspec = type_function_get_retdeclspec(func->declspec.type);
-+ type_t *rettype = retdeclspec->type;
- int has_ret = !is_void( rettype );
-- const var_list_t *args = type_get_function_args( func->type );
-+ const var_list_t *args = type_function_get_args( func->declspec.type );
- const var_t *arg;
- int len, needs_params = 0;
-
-@@ -4964,7 +5003,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 )
-@@ -5001,7 +5040,7 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu
- if (has_ret)
- {
- print_file( file, 1, "return (" );
-- write_type_decl_left(file, rettype);
-+ write_declspec_decl_left(file, retdeclspec);
- fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" );
- }
- print_file( file, 0, "}\n\n");
-@@ -5029,7 +5068,7 @@ void write_exceptions( FILE *file )
- fprintf( file, " EXCEPTION_REGISTRATION_RECORD frame; \\\n");
- fprintf( file, " __filter_func filter; \\\n");
- fprintf( file, " __finally_func finally; \\\n");
-- fprintf( file, " sigjmp_buf jmp; \\\n");
-+ fprintf( file, " __wine_jmp_buf jmp; \\\n");
- fprintf( file, " DWORD code; \\\n");
- fprintf( file, " unsigned char abnormal_termination; \\\n");
- fprintf( file, " unsigned char filter_level; \\\n");
-@@ -5049,13 +5088,13 @@ void write_exceptions( FILE *file )
- fprintf( file, " __wine_pop_frame( &exc_frame->frame );\n");
- fprintf( file, " }\n");
- fprintf( file, " exc_frame->filter_level = 0;\n");
-- fprintf( file, " siglongjmp( exc_frame->jmp, 1 );\n");
-+ fprintf( file, " __wine_longjmp( &exc_frame->jmp, 1 );\n");
- fprintf( file, "}\n");
- fprintf( file, "\n");
-- fprintf( file, "static DWORD __widl_exception_handler( EXCEPTION_RECORD *record,\n");
-- fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
-- fprintf( file, " CONTEXT *context,\n");
-- fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
-+ fprintf( file, "static DWORD __cdecl __widl_exception_handler( EXCEPTION_RECORD *record,\n");
-+ fprintf( file, " EXCEPTION_REGISTRATION_RECORD *frame,\n");
-+ fprintf( file, " CONTEXT *context,\n");
-+ fprintf( file, " EXCEPTION_REGISTRATION_RECORD **pdispatcher )\n");
- fprintf( file, "{\n");
- fprintf( file, " struct __exception_frame *exc_frame = (struct __exception_frame *)frame;\n");
- fprintf( file, "\n");
-@@ -5075,7 +5114,7 @@ void write_exceptions( FILE *file )
- fprintf( file, "}\n");
- fprintf( file, "\n");
- fprintf( file, "#define RpcTryExcept \\\n");
-- fprintf( file, " if (!sigsetjmp( __frame->jmp, 0 )) \\\n");
-+ fprintf( file, " if (!__wine_setjmpex( &__frame->jmp, &__frame->frame )) \\\n");
- fprintf( file, " { \\\n");
- fprintf( file, " if (!__frame->finally_level) \\\n" );
- fprintf( file, " __wine_push_frame( &__frame->frame ); \\\n");
-diff --git a/mingw-w64-tools/widl/src/typelib.c b/mingw-w64-tools/widl/src/typelib.c
-index 9b1de2c8..2c2b1276 100644
---- a/mingw-w64-tools/widl/src/typelib.c
-+++ b/mingw-w64-tools/widl/src/typelib.c
-@@ -97,9 +97,9 @@ static unsigned short builtin_vt(const type_t *t)
- {
- const type_t *elem_type;
- if (is_array(t))
-- elem_type = type_array_get_element(t);
-+ elem_type = type_array_get_element_type(t);
- else
-- elem_type = type_pointer_get_ref(t);
-+ elem_type = type_pointer_get_ref_type(t);
- if (type_get_type(elem_type) == TYPE_BASIC)
- {
- switch (type_basic_get_type(elem_type))
-@@ -129,7 +129,8 @@ unsigned short get_type_vt(type_t *t)
- if (vt) return vt;
- }
-
-- if (type_is_alias(t) && is_attr(t->attrs, ATTR_PUBLIC))
-+ if (type_is_alias(t) &&
-+ (is_attr(t->attrs, ATTR_PUBLIC) || is_attr(t->attrs, ATTR_WIREMARSHAL)))
- return VT_USERDEFINED;
-
- switch (type_get_type(t)) {
-@@ -169,7 +170,7 @@ unsigned short get_type_vt(type_t *t)
- else
- return VT_I8;
- case TYPE_BASIC_INT3264:
-- if (typelib_kind == SYS_WIN64)
-+ if (pointer_size == 8)
- {
- if (type_basic_get_sign(t) > 0)
- return VT_UI8;
-@@ -198,7 +199,7 @@ unsigned short get_type_vt(type_t *t)
- case TYPE_ARRAY:
- if (type_array_is_decl_as_ptr(t))
- {
-- if (match(type_array_get_element(t)->name, "SAFEARRAY"))
-+ if (match(type_array_get_element_type(t)->name, "SAFEARRAY"))
- return VT_SAFEARRAY;
- return VT_PTR;
- }
-diff --git a/mingw-w64-tools/widl/src/typetree.c b/mingw-w64-tools/widl/src/typetree.c
-index b93806be..488f7a49 100644
---- a/mingw-w64-tools/widl/src/typetree.c
-+++ b/mingw-w64-tools/widl/src/typetree.c
-@@ -30,12 +30,16 @@
- #include "typetree.h"
- #include "header.h"
-
--type_t *duptype(type_t *t, int dupname)
-+/* this function is only used in declare_var in parser.y, see FIXME note */
-+type_t *dup_pointer_type(type_t *t)
- {
-- type_t *d = alloc_type();
-+ type_t *d;
-
-+ assert(is_ptr(t) && t->details.pointer.def_fc != FC_RP);
-+
-+ d = alloc_type();
- *d = *t;
-- if (dupname && t->name)
-+ if (t->name)
- d->name = xstrdup(t->name);
-
- return d;
-@@ -49,7 +53,6 @@ type_t *make_type(enum type_type type)
- t->type_type = type;
- t->attrs = NULL;
- t->c_name = NULL;
-- t->orig = NULL;
- memset(&t->details, 0, sizeof(t->details));
- t->typestring_offset = 0;
- t->ptrdesc = 0;
-@@ -137,7 +140,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 +150,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)
- {
-@@ -178,34 +181,28 @@ type_t *type_new_function(var_list_t *args)
- return t;
- }
-
--type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
-+type_t *type_new_pointer(unsigned char pointer_default, type_t *ref)
- {
- type_t *t = make_type(TYPE_POINTER);
- t->details.pointer.def_fc = pointer_default;
-- t->details.pointer.ref = ref;
-- t->attrs = attrs;
-+ t->details.pointer.ref.type = ref;
- return t;
- }
-
--type_t *type_new_alias(type_t *t, const char *name)
-+type_t *type_new_alias(const decl_spec_t *ds, const char *name)
- {
-- type_t *a = duptype(t, 0);
--
-+ type_t *a = make_type(ds->type->type_type);
- a->name = xstrdup(name);
- a->attrs = NULL;
-- a->orig = t;
-+ a->details.alias.aliasee = *ds;
- a->is_alias = TRUE;
-- /* for pointer types */
-- a->details = t->details;
-- init_loc_info(&a->loc_info);
--
- return a;
- }
-
- type_t *type_new_module(char *name)
- {
- type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
-- if (type->type_type != TYPE_MODULE || type->defined)
-+ if (type->type_type != TYPE_MODULE || type_is_defined(type))
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- type->name, type->loc_info.input_name, type->loc_info.line_number);
- type->name = name;
-@@ -215,7 +212,7 @@ type_t *type_new_module(char *name)
- type_t *type_new_coclass(char *name)
- {
- type_t *type = get_type(TYPE_COCLASS, name, NULL, 0);
-- if (type->type_type != TYPE_COCLASS || type->defined)
-+ if (type->type_type != TYPE_COCLASS || type_is_defined(type))
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- type->name, type->loc_info.input_name, type->loc_info.line_number);
- type->name = name;
-@@ -223,7 +220,7 @@ type_t *type_new_coclass(char *name)
- }
-
-
--type_t *type_new_array(const char *name, type_t *element, int declptr,
-+type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
- unsigned int dim, expr_t *size_is, expr_t *length_is,
- unsigned char ptr_default_fc)
- {
-@@ -235,7 +232,9 @@ type_t *type_new_array(const char *name, type_t *element, int declptr,
- t->details.array.size_is = size_is;
- else
- t->details.array.dim = dim;
-- t->details.array.elem = element;
-+ if (element) {
-+ t->details.array.elem = *element;
-+ }
- t->details.array.ptr_def_fc = ptr_default_fc;
- return t;
- }
-@@ -273,80 +272,99 @@ type_t *type_new_void(void)
-
- type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
- {
-- type_t *tag_type = name ? find_type(name, namespace, tsENUM) : NULL;
-- type_t *t = make_type(TYPE_ENUM);
-- t->name = name;
-- t->namespace = namespace;
--
-- if (tag_type && tag_type->details.enumeration)
-- t->details.enumeration = tag_type->details.enumeration;
-- else if (defined)
-+ type_t *t = NULL;
-+
-+ if (name)
-+ t = find_type(name, namespace, tsENUM);
-+
-+ if (!t)
- {
-- t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
-- t->details.enumeration->enums = enums;
-- t->defined = TRUE;
-+ t = make_type(TYPE_ENUM);
-+ t->name = name;
-+ t->namespace = namespace;
-+ if (name)
-+ reg_type(t, name, namespace, tsENUM);
- }
-
-- if (name)
-+ if (!type_is_defined(t))
- {
- if (defined)
-- reg_type(t, name, namespace, tsENUM);
-+ {
-+ t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
-+ t->details.enumeration->enums = enums;
-+ t->defined = TRUE;
-+ }
- else
-+ {
- add_incomplete(t);
-+ }
- }
-+
- return t;
- }
-
- type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields)
- {
-- type_t *tag_type = name ? find_type(name, namespace, tsSTRUCT) : NULL;
-- type_t *t;
--
-- /* avoid creating duplicate typelib type entries */
-- if (tag_type && do_typelib) return tag_type;
-+ type_t *t = NULL;
-
-- t = make_type(TYPE_STRUCT);
-- t->name = name;
-- t->namespace = namespace;
-+ if (name)
-+ t = find_type(name, namespace, tsSTRUCT);
-
-- if (tag_type && tag_type->details.structure)
-- t->details.structure = tag_type->details.structure;
-- else if (defined)
-+ if (!t)
- {
-- t->details.structure = xmalloc(sizeof(*t->details.structure));
-- t->details.structure->fields = fields;
-- t->defined = TRUE;
-+ t = make_type(TYPE_STRUCT);
-+ t->name = name;
-+ t->namespace = namespace;
-+ if (name)
-+ reg_type(t, name, namespace, tsSTRUCT);
- }
-- if (name)
-+
-+ if (!type_is_defined(t))
- {
- if (defined)
-- reg_type(t, name, namespace, tsSTRUCT);
-+ {
-+ t->details.structure = xmalloc(sizeof(*t->details.structure));
-+ t->details.structure->fields = fields;
-+ t->defined = TRUE;
-+ }
- else
-+ {
- add_incomplete(t);
-+ }
- }
-+
- return t;
- }
-
- type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields)
- {
-- type_t *tag_type = name ? find_type(name, NULL, tsUNION) : NULL;
-- type_t *t = make_type(TYPE_UNION);
-- t->name = name;
-- if (tag_type && tag_type->details.structure)
-- t->details.structure = tag_type->details.structure;
-- else if (defined)
-+ type_t *t = NULL;
-+
-+ if (name)
-+ t = find_type(name, NULL, tsUNION);
-+
-+ if (!t)
- {
-- t->details.structure = xmalloc(sizeof(*t->details.structure));
-- t->details.structure->fields = fields;
-- t->defined = TRUE;
-+ t = make_type(TYPE_UNION);
-+ t->name = name;
-+ if (name)
-+ reg_type(t, name, NULL, tsUNION);
- }
-- if (name)
-+
-+ if (!type_is_defined(t))
- {
- if (defined)
-- reg_type(t, name, NULL, tsUNION);
-+ {
-+ t->details.structure = xmalloc(sizeof(*t->details.structure));
-+ t->details.structure->fields = fields;
-+ t->defined = TRUE;
-+ }
- else
-+ {
- add_incomplete(t);
-+ }
- }
-+
- return t;
- }
-
-@@ -354,7 +372,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 +448,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;
-@@ -438,6 +456,7 @@ static int compute_method_indexes(type_t *iface)
-
- void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
- {
-+ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
- iface->details.iface = xmalloc(sizeof(*iface->details.iface));
- iface->details.iface->disp_props = NULL;
- iface->details.iface->disp_methods = NULL;
-@@ -451,6 +470,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
-
- void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
- {
-+ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
- iface->details.iface = xmalloc(sizeof(*iface->details.iface));
- iface->details.iface->disp_props = props;
- iface->details.iface->disp_methods = methods;
-@@ -465,6 +485,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
-
- void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
- {
-+ assert(type_get_type_detect_alias(iface) == TYPE_INTERFACE);
- dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
- dispiface->details.iface->disp_props = NULL;
- dispiface->details.iface->disp_methods = NULL;
-@@ -479,6 +500,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
-
- void type_module_define(type_t *module, statement_list_t *stmts)
- {
-+ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
- if (module->details.module) error_loc("multiple definition error\n");
- module->details.module = xmalloc(sizeof(*module->details.module));
- module->details.module->stmts = stmts;
-@@ -487,6 +509,7 @@ void type_module_define(type_t *module, statement_list_t *stmts)
-
- type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
- {
-+ assert(type_get_type_detect_alias(coclass) == TYPE_COCLASS);
- coclass->details.coclass.ifaces = ifaces;
- coclass->defined = TRUE;
- return coclass;
-diff --git a/mingw-w64-tools/widl/src/typetree.h b/mingw-w64-tools/widl/src/typetree.h
-index fc134cd5..96fcae8d 100644
---- a/mingw-w64-tools/widl/src/typetree.h
-+++ b/mingw-w64-tools/widl/src/typetree.h
-@@ -30,10 +30,10 @@ enum name_type {
- };
-
- type_t *type_new_function(var_list_t *args);
--type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
--type_t *type_new_alias(type_t *t, const char *name);
-+type_t *type_new_pointer(unsigned char pointer_default, type_t *ref);
-+type_t *type_new_alias(const decl_spec_t *aliasee, const char *name);
- type_t *type_new_module(char *name);
--type_t *type_new_array(const char *name, type_t *element, int declptr,
-+type_t *type_new_array(const char* name, const decl_spec_t *element, int declptr,
- unsigned int dim, expr_t *size_is, expr_t *length_is,
- unsigned char ptr_default_fc);
- type_t *type_new_basic(enum type_basic_type basic_type);
-@@ -53,14 +53,38 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
- int type_is_equal(const type_t *type1, const type_t *type2);
- const char *type_get_name(const type_t *type, enum name_type name_type);
-
--/* FIXME: shouldn't need to export this */
--type_t *duptype(type_t *t, int dupname);
-+/* copy pointer type to deal with need for duplicate typeformat strings */
-+type_t *dup_pointer_type(type_t *t);
-+
-+#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
-+ if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
-+ if (stmt->type == STMT_DECLARATION && stmt->u.var->declspec.stgclass == STG_NONE && \
-+ type_get_type_detect_alias(stmt->u.var->declspec.type) == TYPE_FUNCTION)
-+
-+static inline enum type_type type_get_type_detect_alias(const type_t *type)
-+{
-+ if (type->is_alias)
-+ return TYPE_ALIAS;
-+ return type->type_type;
-+}
-+
-+static inline int statements_has_func(const statement_list_t *stmts)
-+{
-+ const statement_t *stmt;
-+ int has_func = 0;
-+ STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
-+ {
-+ has_func = 1;
-+ break;
-+ }
-+ return has_func;
-+}
-
- /* un-alias the type until finding the non-alias type */
- static inline type_t *type_get_real_type(const type_t *type)
- {
- if (type->is_alias)
-- return type_get_real_type(type->orig);
-+ return type_get_real_type(type->details.alias.aliasee.type);
- else
- return (type_t *)type;
- }
-@@ -105,9 +129,14 @@ static inline var_t *type_function_get_retval(const type_t *type)
- return type->details.function->retval;
- }
-
-+static inline const decl_spec_t *type_function_get_retdeclspec(const type_t *type)
-+{
-+ return &type_function_get_retval(type)->declspec;
-+}
-+
- static inline type_t *type_function_get_rettype(const type_t *type)
- {
-- return type_function_get_retval(type)->type;
-+ return type_function_get_retdeclspec(type)->type;
- }
-
- static inline var_list_t *type_enum_get_values(const type_t *type)
-@@ -142,7 +171,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;
-@@ -250,11 +279,16 @@ static inline expr_t *type_array_get_variance(const type_t *type)
- return type->details.array.length_is;
- }
-
--static inline type_t *type_array_get_element(const type_t *type)
-+static inline const decl_spec_t *type_array_get_element(const type_t *type)
- {
- type = type_get_real_type(type);
- assert(type_get_type(type) == TYPE_ARRAY);
-- return type->details.array.elem;
-+ return &type->details.array.elem;
-+}
-+
-+static inline type_t *type_array_get_element_type(const type_t *type)
-+{
-+ return type_array_get_element(type)->type;
- }
-
- static inline int type_array_is_decl_as_ptr(const type_t *type)
-@@ -276,10 +310,15 @@ static inline int type_is_alias(const type_t *type)
- return type->is_alias;
- }
-
--static inline type_t *type_alias_get_aliasee(const type_t *type)
-+static inline const decl_spec_t *type_alias_get_aliasee(const type_t *type)
- {
- assert(type_is_alias(type));
-- return type->orig;
-+ return &type->details.alias.aliasee;
-+}
-+
-+static inline type_t *type_alias_get_aliasee_type(const type_t *type)
-+{
-+ return type_alias_get_aliasee(type)->type;
- }
-
- static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
-@@ -289,11 +328,16 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
- return type->details.coclass.ifaces;
- }
-
--static inline type_t *type_pointer_get_ref(const type_t *type)
-+static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
- {
- type = type_get_real_type(type);
- assert(type_get_type(type) == TYPE_POINTER);
-- return type->details.pointer.ref;
-+ return &type->details.pointer.ref;
-+}
-+
-+static inline type_t *type_pointer_get_ref_type(const type_t *type)
-+{
-+ return type_pointer_get_ref(type)->type;
- }
-
- static inline unsigned char type_pointer_get_default_fc(const type_t *type)
-@@ -317,4 +361,54 @@ static inline const expr_t *type_bitfield_get_bits(const type_t *type)
- return type->details.bitfield.bits;
- }
-
-+/* gets pointer to details_t union with the assumption the caller wants to write to it
-+ * so assert if we're actually dealing with an alias and writing to the details would
-+ * overwrite the alias_details
-+ */
-+static inline details_t *type_get_details(type_t* type)
-+{
-+ assert(!type_is_alias(type));
-+ return &type->details;
-+}
-+
-+/* const overload of type_get_details */
-+
-+static inline const details_t *type_get_const_details(const type_t* type)
-+{
-+ assert(!type_is_alias(type));
-+ return &type->details;
-+}
-+
-+static inline int type_is_pointerish(const type_t *type)
-+{
-+ type = type_get_real_type(type);
-+ return type_get_type(type) == TYPE_ARRAY || type_get_type(type) == TYPE_POINTER;
-+}
-+
-+static inline type_t * type_get_pointer_chain_tail(const type_t *type)
-+{
-+ type_t *pointee = NULL;
-+ type_t *pointer = type_get_real_type(type);
-+
-+ if (type_get_type(pointer) == TYPE_ARRAY)
-+ {
-+ pointee = type_array_get_element_type(pointer);
-+ }
-+ else if (type_get_type(pointer) == TYPE_POINTER)
-+ {
-+ pointee = type_pointer_get_ref_type(pointer);
-+ }
-+ else
-+ {
-+ assert(FALSE);
-+ }
-+
-+ if (type_is_pointerish(pointee))
-+ {
-+ return type_get_pointer_chain_tail(pointee);
-+ }
-+
-+ return pointee;
-+}
-+
- #endif /* WIDL_TYPE_TREE_H */
-diff --git a/mingw-w64-tools/widl/src/widl.c b/mingw-w64-tools/widl/src/widl.c
-index 1af42509..8542e518 100644
---- a/mingw-w64-tools/widl/src/widl.c
-+++ b/mingw-w64-tools/widl/src/widl.c
-@@ -44,11 +44,6 @@
- #include "header.h"
- #include "pathtools.h"
-
--/* future options to reserve characters for: */
--/* A = ACF input filename */
--/* J = do not search standard include path */
--/* w = select win16/win32 output (?) */
--
- static const char usage[] =
- "Usage: widl [options...] infile.idl\n"
- " or: widl [options...] --dlldata-only name1 [name2...]\n"
-@@ -64,7 +59,7 @@ static const char usage[] =
- " -H file Name of header file (default is infile.h)\n"
- " -I path Set include search dir to path (multiple -I allowed)\n"
- " --local-stubs=file Write empty stubs for call_as/local methods to file\n"
--" -m32, -m64 Set the kind of typelib to build (Win32 or Win64)\n"
-+" -m32, -m64 Set the target architecture (Win32 or Win64)\n"
- " -N Do not preprocess input\n"
- " --oldnames Use old naming conventions\n"
- " -o, --output=NAME Set the output file name\n"
-@@ -82,8 +77,7 @@ static const char usage[] =
- " -u Generate interface identifiers file\n"
- " -V Print version and exit\n"
- " -W Enable pedantic warnings\n"
--" --win32 Only generate 32-bit code\n"
--" --win64 Only generate 64-bit code\n"
-+" --win32, --win64 Set the target architecture (Win32 or Win64)\n"
- " --win32-align n Set win32 structure alignment to 'n'\n"
- " --win64-align n Set win64 structure alignment to 'n'\n"
- "Debug level 'n' is a bitmask with following meaning:\n"
-@@ -98,6 +92,20 @@ static const char usage[] =
- static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
- "Copyright 2002 Ove Kaaven\n";
-
-+#ifdef __i386__
-+enum target_cpu target_cpu = CPU_x86;
-+#elif defined(__x86_64__)
-+enum target_cpu target_cpu = CPU_x86_64;
-+#elif defined(__powerpc__)
-+enum target_cpu target_cpu = CPU_POWERPC;
-+#elif defined(__arm__)
-+enum target_cpu target_cpu = CPU_ARM;
-+#elif defined(__aarch64__)
-+enum target_cpu target_cpu = CPU_ARM64;
-+#else
-+#error Unsupported CPU
-+#endif
-+
- int debuglevel = DEBUGLEVEL_NONE;
- int parser_debug, yy_flex_debug;
-
-@@ -114,8 +122,6 @@ int do_idfile = 0;
- int do_dlldata = 0;
- static int no_preprocess = 0;
- int old_names = 0;
--int do_win32 = 1;
--int do_win64 = 1;
- int win32_packing = 8;
- int win64_packing = 8;
- int winrt_mode = 0;
-@@ -148,7 +154,6 @@ int line_number = 1;
- static FILE *idfile;
-
- unsigned int pointer_size = 0;
--syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
-
- time_t now;
-
-@@ -188,6 +193,7 @@ static const struct option long_options[] = {
- { "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
- { "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
- { "robust", 0, NULL, ROBUST_OPTION },
-+ { "target", 0, NULL, 'b' },
- { "winrt", 0, NULL, RT_OPTION },
- { "win32", 0, NULL, WIN32_OPTION },
- { "win64", 0, NULL, WIN64_OPTION },
-@@ -269,20 +275,25 @@ static void set_target( const char *target )
- {
- static const struct
- {
-- const char *name;
-- syskind_t kind;
-+ const char *name;
-+ enum target_cpu cpu;
- } cpu_names[] =
- {
-- { "i386", SYS_WIN32 },
-- { "i486", SYS_WIN32 },
-- { "i586", SYS_WIN32 },
-- { "i686", SYS_WIN32 },
-- { "i786", SYS_WIN32 },
-- { "amd64", SYS_WIN64 },
-- { "x86_64", SYS_WIN64 },
-- { "powerpc", SYS_WIN32 },
-- { "arm", SYS_WIN32 },
-- { "aarch64", SYS_WIN64 }
-+ { "i386", CPU_x86 },
-+ { "i486", CPU_x86 },
-+ { "i586", CPU_x86 },
-+ { "i686", CPU_x86 },
-+ { "i786", CPU_x86 },
-+ { "amd64", CPU_x86_64 },
-+ { "x86_64", CPU_x86_64 },
-+ { "powerpc", CPU_POWERPC },
-+ { "arm", CPU_ARM },
-+ { "armv5", CPU_ARM },
-+ { "armv6", CPU_ARM },
-+ { "armv7", CPU_ARM },
-+ { "armv7a", CPU_ARM },
-+ { "arm64", CPU_ARM64 },
-+ { "aarch64", CPU_ARM64 },
- };
-
- unsigned int i;
-@@ -296,7 +307,7 @@ static void set_target( const char *target )
- {
- if (!strcmp( cpu_names[i].name, spec ))
- {
-- typelib_kind = cpu_names[i].kind;
-+ target_cpu = cpu_names[i].cpu;
- free( spec );
- return;
- }
-@@ -484,6 +495,7 @@ static void write_id_data_stmts(const statement_list_t *stmts)
- uuid = get_attrp(type->attrs, ATTR_UUID);
- write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
- type->name, uuid);
-+ assert(type_get_type_detect_alias(type) == TYPE_INTERFACE);
- if (type->details.iface->async_iface)
- {
- uuid = get_attrp(type->details.iface->async_iface->attrs, ATTR_UUID);
-@@ -606,12 +618,10 @@ int main(int argc,char *argv[])
- use_abi_namespace = 1;
- break;
- case WIN32_OPTION:
-- do_win32 = 1;
-- do_win64 = 0;
-+ pointer_size = 4;
- break;
- case WIN64_OPTION:
-- do_win32 = 0;
-- do_win64 = 1;
-+ pointer_size = 8;
- break;
- case WIN32_ALIGN_OPTION:
- win32_packing = strtol(optarg, NULL, 0);
-@@ -664,8 +674,8 @@ int main(int argc,char *argv[])
- wpp_add_include_path(optarg);
- break;
- case 'm':
-- if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32;
-- else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64;
-+ if (!strcmp( optarg, "32" )) pointer_size = 4;
-+ else if (!strcmp( optarg, "64" )) pointer_size = 8;
- break;
- case 'N':
- no_preprocess = 1;
-@@ -726,6 +736,7 @@ int main(int argc,char *argv[])
- }
-
- #ifdef DEFAULT_INCLUDE_DIR
-+ wpp_add_include_path(DEFAULT_INCLUDE_DIR);
- char exe_path[PATH_MAX];
- get_executable_path (argv[0], &exe_path[0], sizeof (exe_path) / sizeof (exe_path[0]));
- char * rel_to_includedir = get_relative_path (DEFAULT_BINDIR, DEFAULT_INCLUDE_DIR);
-@@ -739,6 +750,26 @@ int main(int argc,char *argv[])
- wpp_add_include_path(relocated_default_include_dir);
- #endif
-
-+ switch (target_cpu)
-+ {
-+ case CPU_x86:
-+ if (pointer_size == 8) target_cpu = CPU_x86_64;
-+ else pointer_size = 4;
-+ break;
-+ case CPU_x86_64:
-+ if (pointer_size == 4) target_cpu = CPU_x86;
-+ else pointer_size = 8;
-+ break;
-+ case CPU_ARM64:
-+ if (pointer_size == 4) error( "Cannot build 32-bit code for this CPU\n" );
-+ pointer_size = 8;
-+ break;
-+ default:
-+ if (pointer_size == 8) error( "Cannot build 64-bit code for this CPU\n" );
-+ pointer_size = 4;
-+ break;
-+ }
-+
- /* if nothing specified, try to guess output type from the output file name */
- if (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
- !do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata)
-diff --git a/mingw-w64-tools/widl/src/widl.h b/mingw-w64-tools/widl/src/widl.h
-index 118e2245..4f4252e3 100644
---- a/mingw-w64-tools/widl/src/widl.h
-+++ b/mingw-w64-tools/widl/src/widl.h
-@@ -45,8 +45,6 @@ extern int do_regscript;
- extern int do_idfile;
- extern int do_dlldata;
- extern int old_names;
--extern int do_win32;
--extern int do_win64;
- extern int win32_packing;
- extern int win64_packing;
- extern int winrt_mode;
-@@ -76,6 +74,13 @@ extern time_t now;
- extern int line_number;
- extern int char_number;
-
-+enum target_cpu
-+{
-+ CPU_x86, CPU_x86_64, CPU_POWERPC, CPU_ARM, CPU_ARM64, CPU_LAST = CPU_ARM64
-+};
-+
-+extern enum target_cpu target_cpu;
-+
- enum stub_mode
- {
- MODE_Os, /* inline stubs */
-diff --git a/mingw-w64-tools/widl/src/widltypes.h b/mingw-w64-tools/widl/src/widltypes.h
-index 08584de5..cd71e9af 100644
---- a/mingw-w64-tools/widl/src/widltypes.h
-+++ b/mingw-w64-tools/widl/src/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;
-@@ -80,7 +81,6 @@ enum attr_type
- ATTR_CASE,
- ATTR_CODE,
- ATTR_COMMSTATUS,
-- ATTR_CONST, /* const pseudo-attribute */
- ATTR_CONTEXTHANDLE,
- ATTR_CONTROL,
- ATTR_DECODE,
-@@ -115,7 +115,6 @@ enum attr_type
- ATTR_IMMEDIATEBIND,
- ATTR_IMPLICIT_HANDLE,
- ATTR_IN,
-- ATTR_INLINE,
- ATTR_INPUTSYNC,
- ATTR_LENGTHIS,
- ATTR_LIBLCID,
-@@ -234,6 +233,18 @@ enum storage_class
- STG_REGISTER,
- };
-
-+enum type_qualifier
-+{
-+ TYPE_QUALIFIER_NONE = 0,
-+ TYPE_QUALIFIER_CONST = 1,
-+};
-+
-+enum function_specifier
-+{
-+ FUNCTION_SPECIFIER_NONE,
-+ FUNCTION_SPECIFIER_INLINE,
-+};
-+
- enum statement_type
- {
- STMT_LIBRARY,
-@@ -293,6 +304,14 @@ struct str_list_entry_t
- struct list entry;
- };
-
-+struct _decl_spec_t
-+{
-+ type_t *type;
-+ enum storage_class stgclass;
-+ enum type_qualifier typequalifier;
-+ enum function_specifier funcspecifier;
-+};
-+
- struct _attr_t {
- enum attr_type type;
- union {
-@@ -356,7 +375,7 @@ struct array_details
- {
- expr_t *size_is;
- expr_t *length_is;
-- struct _type_t *elem;
-+ struct _decl_spec_t elem;
- unsigned int dim;
- unsigned char ptr_def_fc;
- unsigned char declptr; /* if declared as a pointer */
-@@ -376,7 +395,7 @@ struct basic_details
-
- struct pointer_details
- {
-- struct _type_t *ref;
-+ struct _decl_spec_t ref;
- unsigned char def_fc;
- };
-
-@@ -386,6 +405,11 @@ struct bitfield_details
- const expr_t *bits;
- };
-
-+struct alias_details
-+{
-+ struct _decl_spec_t aliasee;
-+};
-+
- #define HASHMAX 64
-
- struct namespace {
-@@ -414,26 +438,28 @@ enum type_type
- TYPE_BITFIELD,
- };
-
-+typedef union _details_t
-+{
-+ struct struct_details *structure;
-+ struct enumeration_details *enumeration;
-+ struct func_details *function;
-+ struct iface_details *iface;
-+ struct module_details *module;
-+ struct array_details array;
-+ struct coclass_details coclass;
-+ struct basic_details basic;
-+ struct pointer_details pointer;
-+ struct bitfield_details bitfield;
-+ struct alias_details alias;
-+} details_t;
-+
- struct _type_t {
- const char *name;
- struct namespace *namespace;
- enum type_type type_type;
- attr_list_t *attrs;
-- union
-- {
-- struct struct_details *structure;
-- struct enumeration_details *enumeration;
-- struct func_details *function;
-- struct iface_details *iface;
-- struct module_details *module;
-- struct array_details array;
-- struct coclass_details coclass;
-- struct basic_details basic;
-- struct pointer_details pointer;
-- struct bitfield_details bitfield;
-- } details;
-+ details_t details;
- const char *c_name;
-- type_t *orig; /* dup'd types */
- unsigned int typestring_offset;
- unsigned int ptrdesc; /* used for complex structs */
- int typelib_idx;
-@@ -449,14 +475,20 @@ 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;
-
- struct _loc_info_t loc_info;
-+ /* this flag indicates that this var's type (or pointed to type in the case of
-+ * array or pointer) was not fully defined at the time of declaration.
-+ * If this flag is set to TRUE then the type definition will not be written for this var
-+ * If this flag is set to FALSE then the type definition will only be written if it has not
-+ * been written yet (determined by the type_t's 'written' flag)
-+ */
-+ int declonly : 1;
-
- /* parser-internal */
- struct list entry;
-@@ -464,7 +496,7 @@ struct _var_t {
-
- struct _declarator_t {
- var_t *var;
-- type_t *type;
-+ decl_spec_t declspec;
- type_t *func_type;
- expr_t *bits;
-
-@@ -497,6 +529,7 @@ struct _importinfo_t {
- };
-
- struct _importlib_t {
-+ int offset;
- char *name;
-
- int version;
-@@ -539,6 +572,13 @@ struct _statement_t {
- typelib_t *lib;
- type_list_t *type_list;
- } u;
-+ /* this flag indicates that this statement's type (or pointed to type in the case of
-+ * array or pointer) was not fully defined at the time of declaration.
-+ * If this flag is set to TRUE then the type definition will not be written for this statement
-+ * If this flag is set to FALSE then the type definition will only be written if it has not
-+ * been written yet (determined by the type_t's 'written' flag)
-+ */
-+ int declonly : 1;
- };
-
- struct _warning_t {
-@@ -553,11 +593,10 @@ typedef enum {
- SYS_WIN64
- } syskind_t;
-
--extern syskind_t typelib_kind;
- extern user_type_list_t user_type_list;
- extern context_handle_list_t context_handle_list;
- extern generic_handle_list_t generic_handle_list;
--void check_for_additional_prototype_types(const var_list_t *list);
-+void check_for_additional_prototype_types(type_t *type);
-
- void init_types(void);
- type_t *alloc_type(void);
-@@ -582,38 +621,18 @@ void init_loc_info(loc_info_t *);
-
- char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix);
-
--static inline var_list_t *type_get_function_args(const type_t *func_type)
--{
-- return func_type->details.function->args;
--}
--
--static inline enum type_type type_get_type_detect_alias(const type_t *type)
--{
-- if (type->is_alias)
-- return TYPE_ALIAS;
-- return type->type_type;
--}
--
--#define STATEMENTS_FOR_EACH_FUNC(stmt, stmts) \
-- if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) \
-- if (stmt->type == STMT_DECLARATION && stmt->u.var->stgclass == STG_NONE && \
-- type_get_type_detect_alias(stmt->u.var->type) == TYPE_FUNCTION)
--
--static inline int statements_has_func(const statement_list_t *stmts)
-+static inline int is_global_namespace(const struct namespace *namespace)
- {
-- const statement_t *stmt;
-- int has_func = 0;
-- STATEMENTS_FOR_EACH_FUNC(stmt, stmts)
-- {
-- has_func = 1;
-- break;
-- }
-- return has_func;
-+ return !namespace->name;
- }
-
--static inline int is_global_namespace(const struct namespace *namespace)
-+static inline decl_spec_t *init_declspec(decl_spec_t *declspec, type_t *type)
- {
-- return !namespace->name;
-+ declspec->type = type;
-+ declspec->stgclass = STG_NONE;
-+ declspec->typequalifier=TYPE_QUALIFIER_NONE;
-+ declspec->funcspecifier=FUNCTION_SPECIFIER_NONE;
-+ return declspec;
- }
-
- #endif
-diff --git a/mingw-w64-tools/widl/src/write_msft.c b/mingw-w64-tools/widl/src/write_msft.c
-index 88a80d12..da7ce89d 100644
---- a/mingw-w64-tools/widl/src/write_msft.c
-+++ b/mingw-w64-tools/widl/src/write_msft.c
-@@ -702,15 +702,15 @@ static void alloc_importinfo(msft_typelib_t *typelib, importinfo_t *importinfo)
-
- guid_idx = ctl2_alloc_guid(typelib, &guid);
-
-- alloc_importfile(typelib, guid_idx, importlib->version&0xffff,
-- importlib->version>>16, importlib->name);
-+ importlib->offset = alloc_importfile(typelib, guid_idx, importlib->version & 0xffff,
-+ importlib->version >> 16, importlib->name);
- }
-
- if(importinfo->offset == -1 || !(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID)) {
- MSFT_ImpInfo impinfo;
-
- impinfo.flags = importinfo->flags;
-- impinfo.oImpFile = 0;
-+ impinfo.oImpFile = importlib->offset;
-
- if(importinfo->flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
- MSFT_GuidEntry guid;
-@@ -763,7 +763,7 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration);
- static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion);
- static void add_coclass_typeinfo(msft_typelib_t *typelib, type_t *cls);
- static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface);
--
-+static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef);
-
- /****************************************************************************
- * encode_type
-@@ -862,8 +862,8 @@ static int encode_type(
- case VT_PTR:
- {
- int next_vt;
-- for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref(type)) {
-- next_vt = get_type_vt(type_pointer_get_ref(type));
-+ for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref_type(type)) {
-+ next_vt = get_type_vt(type_pointer_get_ref_type(type));
- if (next_vt != 0)
- break;
- }
-@@ -871,7 +871,7 @@ static int encode_type(
- if (next_vt == 0)
- next_vt = VT_VOID;
-
-- encode_type(typelib, next_vt, type_pointer_get_ref(type),
-+ encode_type(typelib, next_vt, type_pointer_get_ref_type(type),
- &target_type, &child_size);
- /* these types already have an implicit pointer, so we don't need to
- * add another */
-@@ -912,10 +912,10 @@ static int encode_type(
-
- case VT_SAFEARRAY:
- {
-- type_t *element_type = type_alias_get_aliasee(type_array_get_element(type));
-+ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(type));
- int next_vt = get_type_vt(element_type);
-
-- encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)),
-+ encode_type(typelib, next_vt, type_alias_get_aliasee_type(type_array_get_element_type(type)),
- &target_type, &child_size);
-
- for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
-@@ -966,33 +966,61 @@ static int encode_type(
- }
- else
- {
-- /* typedef'd types without public attribute aren't included in the typelib */
-- while (type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
-- type = type_alias_get_aliasee(type);
-+ /* typedef'd types without public attribute aren't included in the typelib
-+ * typedef'd types with a wire_marshal attribute must be included
-+ */
-+ while (type_is_alias(type))
-+ {
-+ if (is_attr(type->attrs, ATTR_WIREMARSHAL))
-+ {
-+ type = get_attrp(type->attrs, ATTR_WIREMARSHAL);
-+ break;
-+ }
-+ else if(!is_attr(type->attrs, ATTR_PUBLIC))
-+ {
-+ type = type_alias_get_aliasee_type(type);
-+ }
-+ else
-+ {
-+ break;
-+ }
-+ }
-
- chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
- type->name, type_get_type(type));
-
-- switch (type_get_type(type))
-+ /* we've either fully resolved the typedef down to an actual type or
-+ * we must include the typedef because it's a wiremarshal (or public) type
-+ */
-+ if (type_is_alias(type))
- {
-- case TYPE_STRUCT:
-- add_structure_typeinfo(typelib, type);
-- break;
-- case TYPE_INTERFACE:
-- add_interface_typeinfo(typelib, type);
-- break;
-- case TYPE_ENUM:
-- add_enum_typeinfo(typelib, type);
-- break;
-- case TYPE_UNION:
-- add_union_typeinfo(typelib, type);
-- break;
-- case TYPE_COCLASS:
-- add_coclass_typeinfo(typelib, type);
-- break;
-- default:
-- error("encode_type: VT_USERDEFINED - unhandled type %d\n",
-- type_get_type(type));
-+ add_typedef_typeinfo(typelib, type);
-+ }
-+ else
-+ {
-+ switch (type_get_type(type))
-+ {
-+ case TYPE_STRUCT:
-+ add_structure_typeinfo(typelib, type);
-+ break;
-+ case TYPE_INTERFACE:
-+ add_interface_typeinfo(typelib, type);
-+ break;
-+ case TYPE_ENUM:
-+ add_enum_typeinfo(typelib, type);
-+ break;
-+ /* fallthrough */
-+ case TYPE_UNION:
-+ case TYPE_ENCAPSULATED_UNION:
-+ add_union_typeinfo(typelib, type);
-+ break;
-+ case TYPE_COCLASS:
-+ add_coclass_typeinfo(typelib, type);
-+ break;
-+ default:
-+ error("encode_type: VT_USERDEFINED - unhandled type %d\n",
-+ type_get_type(type));
-+ }
- }
-
- typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
-@@ -1056,7 +1084,7 @@ static int encode_var(
- num_dims = 0;
- for (atype = type;
- is_array(atype) && !type_array_is_decl_as_ptr(atype);
-- atype = type_array_get_element(atype))
-+ atype = type_array_get_element_type(atype))
- ++num_dims;
-
- chat("array with %d dimensions\n", num_dims);
-@@ -1071,7 +1099,7 @@ static int encode_var(
- arraydata += 2;
- for (atype = type;
- is_array(atype) && !type_array_is_decl_as_ptr(atype);
-- atype = type_array_get_element(atype))
-+ atype = type_array_get_element_type(atype))
- {
- arraydata[0] = type_array_get_dim(atype);
- arraydata[1] = 0;
-@@ -1093,7 +1121,7 @@ static int encode_var(
- vt = get_type_vt(type);
- if (vt == VT_PTR) {
- type_t *ref = is_ptr(type) ?
-- type_pointer_get_ref(type) : type_array_get_element(type);
-+ type_pointer_get_ref_type(type) : type_array_get_element_type(type);
- int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
-
- if(skip_ptr == 2) {
-@@ -1114,7 +1142,7 @@ static int encode_var(
- if (target_type & 0x80000000) {
- mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
- } else if (get_type_vt(ref) == VT_SAFEARRAY) {
-- type_t *element_type = type_alias_get_aliasee(type_array_get_element(ref));
-+ type_t *element_type = type_alias_get_aliasee_type(type_array_get_element_type(ref));
- mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
- } else {
- typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][target_type];
-@@ -1204,7 +1232,7 @@ static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *e
- if (type_get_type(type) == TYPE_ENUM) {
- vt = VT_I4;
- } else if (is_ptr(type)) {
-- vt = get_type_vt(type_pointer_get_ref(type));
-+ vt = get_type_vt(type_pointer_get_ref_type(type));
- if (vt == VT_USERDEFINED)
- vt = VT_I4;
- if (expr->cval)
-@@ -1301,8 +1329,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_function_get_args(func->declspec.type))
-+ LIST_FOR_EACH_ENTRY( arg, type_function_get_args(func->declspec.type), var_t, entry )
- {
- num_params++;
- if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
-@@ -1444,7 +1472,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 +1499,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_function_get_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_function_get_args(func->declspec.type), var_t, entry )
- {
- int paramflags = 0;
- int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3;
-@@ -1482,13 +1510,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 +1600,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_function_get_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_function_get_args(func->declspec.type), var_t, entry )
- {
- /* don't give the last arg of a [propput*] func a name */
- if(i != num_params - 1 || (invokekind != 0x4 /* INVOKE_PROPERTYPUT */ && invokekind != 0x8 /* INVOKE_PROPERTYPUTREF */))
-@@ -1697,8 +1725,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;
-@@ -1977,6 +2005,7 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
- var_t *var;
- msft_typeinfo_t *msft_typeinfo;
-
-+ assert(type_get_type_detect_alias(dispinterface) == TYPE_INTERFACE);
- if (-1 < dispinterface->typelib_idx)
- return;
-
-@@ -2181,7 +2210,7 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
- if (-1 < tdef->typelib_idx)
- return;
-
-- type = type_alias_get_aliasee(tdef);
-+ type = type_alias_get_aliasee_type(tdef);
-
- if (!type->name || strcmp(tdef->name, type->name) != 0)
- {
-@@ -2297,6 +2326,7 @@ static void add_module_typeinfo(msft_typelib_t *typelib, type_t *module)
- const statement_t *stmt;
- msft_typeinfo_t *msft_typeinfo;
-
-+ assert(type_get_type_detect_alias(module) == TYPE_MODULE);
- if (-1 < module->typelib_idx)
- return;
-
-@@ -2364,7 +2394,7 @@ static void add_entry(msft_typelib_t *typelib, const statement_t *stmt)
- if (is_attr(type_entry->type->attrs, ATTR_PUBLIC))
- add_typedef_typeinfo(typelib, type_entry->type);
- else
-- add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type));
-+ add_type_typeinfo(typelib, type_alias_get_aliasee_type(type_entry->type));
- }
- break;
- }
-@@ -2653,8 +2683,6 @@ int create_msft_typelib(typelib_t *typelib)
- GUID midl_info_guid = {0xde77ba65,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
- char info_string[128];
-
-- pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
--
- msft = xmalloc(sizeof(*msft));
- memset(msft, 0, sizeof(*msft));
- msft->typelib = typelib;
-@@ -2662,7 +2690,7 @@ int create_msft_typelib(typelib_t *typelib)
- ctl2_init_header(msft);
- ctl2_init_segdir(msft);
-
-- msft->typelib_header.varflags |= typelib_kind;
-+ msft->typelib_header.varflags |= (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
-
- /*
- * The following two calls return an offset or -1 if out of memory. We
diff --git a/projects/mingw-w64/build b/projects/mingw-w64/build
index faa5997..4be660d 100644
--- a/projects/mingw-w64/build
+++ b/projects/mingw-w64/build
@@ -52,9 +52,6 @@ cd /var/tmp/build/builddir/mingw-w64/mingw-w64-pthread
make -j[% c("buildconf/num_procs") %]
make install
-# patch mingw with widl fixes for #27503 ( https://trac.torproject.org/projects/tor/ticket/27503 )
-patch -p1 -d /var/tmp/build/[% project %]-[% c("version") %] < $rootdir/27503.patch
-
mkdir -p /var/tmp/build/builddir/mingw-w64/widl32
cd /var/tmp/build/builddir/mingw-w64/widl32
/var/tmp/build/[% project %]-[% c("version") %]/mingw-w64-tools/widl/configure \
diff --git a/projects/mingw-w64/config b/projects/mingw-w64/config
index a2f0701..3bb1dda 100644
--- a/projects/mingw-w64/config
+++ b/projects/mingw-w64/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
git_url: https://git.code.sf.net/p/mingw-w64/mingw-w64
-git_hash: 2d4e517ad0c7a9f0bd7001c42e6c131b977c15d9
+git_hash: 2d52c4b3433e55b1c454f9567c0ae9adc4b83b41
version: '[% c("abbrev") %]'
var:
container:
@@ -35,4 +35,3 @@ input_files:
- name: binutils
project: binutils
- filename: libtool-sort.patch
- - filename: 27503.patch
1
0

27 Aug '19
commit 9117a7ac078e6089ca4a0a01f8129206e1195ed9
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Aug 27 15:48:01 2019 +0000
Bug 28119: Tor Browser for aarch64
There is actually no --disable-tor-launcher option on stable yet.
Remove it.
---
projects/firefox/mozconfig-android-aarch64 | 3 ---
1 file changed, 3 deletions(-)
diff --git a/projects/firefox/mozconfig-android-aarch64 b/projects/firefox/mozconfig-android-aarch64
index 2a9eb67..39d0e1d 100644
--- a/projects/firefox/mozconfig-android-aarch64
+++ b/projects/firefox/mozconfig-android-aarch64
@@ -19,9 +19,6 @@ ac_add_options --with-clang-path=/var/tmp/dist/android-toolchain/android-ndk/arm
ac_add_options --with-android-distribution-directory=@TOPSRCDIR@/mobile/android/torbrowser
ac_add_options --with-l10n-base=/var/tmp/dist/locales
-# We do not use Tor Launcher on Android:
-ac_add_options --disable-tor-launcher
-
if [ -z "${TB_BUILD_WITH_UPDATER}" ]; then
# Because Google Play will likely be the primary distribution medium,
# we disable updating and rely on Google Play by default. The
1
0