Duplicated types made it impossible to avoid multiply defining user- defined types (structs, enums, unions). The duptype function has been removed and the remaining code refactored to no longer require it. User-define types are now no longer duplicated in typetree.c However, there is a bit of fallout from this:
Various type attributes (ATTR_EXTERN, ATTR_CONST, and ATTR_INLINE) had to be removed from a type_t's attributes and placed on a new struct _decl_type which itself owned a type_t. This decl_type_t is now passed around in many functions previously expecting type_t.
The _type struct now includes a struct typedef_details in its details union which has the type qualifier (const) info.
The bitfield_details struct also contains a decl_type_t rather than a raw type_t pointer to correctly handle const bits.
Wine fully builds with these changes to widl, and all of the tests for rpcrt4.dll and oleaut32.dll run with the same results.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47035 Signed-off-by: Richard Pospesel richard@torproject.net --- As a side-effect, this patch also fixes: Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47149 --- tools/widl/client.c | 53 ++-- tools/widl/expr.c | 14 +- tools/widl/header.c | 248 +++++++++------- tools/widl/header.h | 11 +- tools/widl/parser.y | 415 ++++++++++++++++---------- tools/widl/proxy.c | 58 ++-- tools/widl/server.c | 19 +- tools/widl/typegen.c | 624 +++++++++++++++++++++------------------- tools/widl/typelib.c | 6 +- tools/widl/typetree.c | 97 ++++--- tools/widl/typetree.h | 57 ++-- tools/widl/widltypes.h | 61 +++- tools/widl/write_msft.c | 56 ++-- 13 files changed, 984 insertions(+), 735 deletions(-)
diff --git a/tools/widl/client.c b/tools/widl/client.c index fe88f5993c..aecbf3e00f 100644 --- a/tools/widl/client.c +++ b/tools/widl/client.c @@ -15,17 +15,17 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#include "config.h" #include "wine/port.h" - + #include <stdio.h> #include <stdlib.h> #ifdef HAVE_UNISTD_H # include <unistd.h> #endif #include <string.h> #include <ctype.h>
@@ -47,41 +47,44 @@ static void print_client( const char *format, ... ) va_list va; va_start(va, format); print(client, indent, format, va); va_end(va); }
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->decltype.type->attrs, ATTR_CALLCONV); + const var_list_t *args = type_get_function_args(func->decltype.type); + decl_type_t *retdecltype = type_function_get_retdecltype(func->decltype.type);
if (!callconv) callconv = "__cdecl"; - write_type_decl_left(client, rettype); + write_decltype_decl_left(client, retdecltype); + if (func->decltype.funcspecifier == FUNCTION_SPECIFIER_INLINE) { + fprintf(client, " inline"); + } fprintf(client, " %s ", callconv); fprintf(client, "%s%s(\n", prefix_client, get_name(func)); indent++; if (args) write_args(client, args, iface->name, 0, TRUE); else print_client("void"); fprintf(client, ")\n"); indent--; }
static void write_function_stub( const type_t *iface, const var_t *func, int method_count, unsigned int proc_offset ) { 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->decltype.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->decltype.type);
if (is_interpreted_func( iface, func )) { write_client_func_decl( iface, func ); write_client_call_routine( client, iface, func, iface->name, proc_offset ); return; }
@@ -92,17 +95,17 @@ static void write_function_stub( const type_t *iface, const var_t *func, if (handle_var) { if (explicit_fc == FC_BIND_GENERIC) print_client("%s %s;\n", get_explicit_generic_handle_type(handle_var)->name, handle_var->name ); print_client("RPC_BINDING_HANDLE _Handle;\n"); }
- if (has_ret && decl_indirect(retval->type)) + if (has_ret && decl_indirect(retval->decltype.type)) { print_client("void *_p_%s;\n", retval->name); } indent--; print_client( "};\n\n" );
print_client( "static void __finally_%s%s(", prefix_client, get_name(func) ); print_client( " struct __frame_%s%s *__frame )\n{\n", prefix_client, get_name(func) ); @@ -131,28 +134,28 @@ static void write_function_stub( const type_t *iface, const var_t *func, fprintf(client, "{\n"); indent++; print_client( "struct __frame_%s%s __f, * const __frame = &__f;\n", prefix_client, get_name(func) );
/* declare return value */ if (has_ret) { print_client("%s", ""); - write_type_decl(client, retval->type, retval->name); + write_decltype_decl(client, (decl_type_t*)&retval->decltype, retval->name); fprintf(client, ";\n"); } print_client("RPC_MESSAGE _RpcMessage;\n");
if (handle_var) { print_client( "__frame->_Handle = 0;\n" ); 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->decltype.type)) { print_client("__frame->_p_%s = &%s;\n", retval->name, retval->name); } fprintf(client, "\n");
print_client( "RpcExceptionInit( 0, __finally_%s%s );\n", prefix_client, get_name(func) );
if (has_full_pointer) @@ -189,17 +192,17 @@ static void write_function_stub( const type_t *iface, const var_t *func, get_explicit_generic_handle_type(handle_var)->name, handle_var->name); fprintf(client, "\n"); break; case FC_BIND_CONTEXT: { /* 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->decltype.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", is_ch_ptr ? "*" : "", handle_var->name); indent--; if (is_attr(handle_var->attrs, ATTR_IN) && !is_attr(handle_var->attrs, ATTR_OUT)) { print_client("else\n"); @@ -252,19 +255,19 @@ static void write_function_stub( const type_t *iface, const var_t *func,
/* unmarshall arguments */ fprintf(client, "\n"); write_remoting_arguments(client, indent, func, "", PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */ if (has_ret) { - if (decl_indirect(retval->type)) + if (decl_indirect(retval->decltype.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->decltype.type) || is_array(retval->decltype.type)) print_client("%s = 0;\n", retval->name); write_remoting_arguments(client, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL); }
indent--; print_client("}\n"); print_client("RpcFinally\n"); print_client("{\n"); @@ -360,28 +363,28 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
LIST_FOR_EACH_ENTRY( stmt, type_iface_get_stmts(iface), const statement_t, entry ) { switch (stmt->type) { 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->decltype.stgclass != STG_NONE + || type_get_type_detect_alias(stmt->u.var->decltype.type) != TYPE_FUNCTION) continue; write_function_stub( iface, func, method_count++, *proc_offset ); *proc_offset += get_size_procformatstring_func( iface, func ); break; } case STMT_TYPEDEF: { - const type_list_t *type_entry; - for (type_entry = stmt->u.type_list; type_entry; type_entry = type_entry->next) - write_serialize_functions(client, type_entry->type, iface); + const typedef_list_t *typedef_entry; + for (typedef_entry = stmt->u.typedef_list; typedef_entry; typedef_entry = typedef_entry->next) + write_serialize_functions(client, typedef_entry->var->decltype.type, iface); break; } default: break; } } }
@@ -483,17 +486,17 @@ static void write_clientinterfacedecl(type_t *iface)
static void write_implicithandledecl(type_t *iface) { const var_t *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
if (implicit_handle) { - write_type_decl( client, implicit_handle->type, implicit_handle->name ); + write_decltype_decl( client, (decl_type_t*)&implicit_handle->decltype, implicit_handle->name ); fprintf(client, ";\n\n"); } }
static void init_client(void) { if (client) return; @@ -527,29 +530,29 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
fprintf(client, "/*****************************************************************************\n"); fprintf(client, " * %s interface\n", iface->name); fprintf(client, " */\n"); fprintf(client, "\n");
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->decltype.stgclass == STG_NONE && + type_get_type_detect_alias(stmt2->u.var->decltype.type) == TYPE_FUNCTION) { needs_stub = 1; break; } if (stmt2->type == STMT_TYPEDEF) { - const type_list_t *type_entry; - for (type_entry = stmt2->u.type_list; type_entry; type_entry = type_entry->next) + const typedef_list_t *typedef_entry; + for (typedef_entry = stmt2->u.typedef_list; typedef_entry; typedef_entry = typedef_entry->next) { - if (is_attr(type_entry->type->attrs, ATTR_ENCODE) - || is_attr(type_entry->type->attrs, ATTR_DECODE)) + if (is_attr(typedef_entry->var->decltype.type->attrs, ATTR_ENCODE) + || is_attr(typedef_entry->var->decltype.type->attrs, ATTR_DECODE)) { needs_stub = 1; break; } } if (needs_stub) break; } diff --git a/tools/widl/expr.c b/tools/widl/expr.c index 2ed4aff6ad..48a78c1c0c 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -189,20 +189,20 @@ expr_t *make_exprs(enum expr_type type, char *val) return e; }
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->decltype.stgclass != STG_NONE && var->decltype.stgclass != STG_REGISTER) error_loc("invalid storage class for type expression\n");
- tref = var->type; + tref = var->decltype.type;
e = xmalloc(sizeof(expr_t)); e->type = type; e->ref = expr; e->u.tref = tref; e->is_const = FALSE; if (type == EXPR_SIZEOF) { @@ -469,25 +469,25 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type, assert(0); break; } }
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) if (field->name && !strcmp(identifier, field->name)) { - type = field->type; + type = field->decltype.type; *found_in_cont_type = 1; break; }
if (!type) { var_t *const_var = find_const(identifier, 0); - if (const_var) type = const_var->type; + if (const_var) type = const_var->decltype.type; }
return type; }
static int is_valid_member_operand(const type_t *type) { switch (type_get_type(type)) @@ -575,20 +575,20 @@ 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); 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 " : "", expr_loc->attr ? expr_loc->attr : ""); break; case EXPR_CAST: result = resolve_expression(expr_loc, cont_type, e->ref); result.type = e->u.tref; @@ -660,17 +660,17 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc result.is_variable = FALSE; break; } case EXPR_ARRAY: result = resolve_expression(expr_loc, cont_type, e->ref); 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", expr_loc->attr ? " for attribute " : "", expr_loc->attr ? expr_loc->attr : ""); } else error_loc_info(&expr_loc->v->loc_info, "array subscript operator applied to non-array type in expression%s%s\n", diff --git a/tools/widl/header.c b/tools/widl/header.c index f618e02f3d..e536c2167c 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -38,17 +38,17 @@ #include "typelib.h"
static int indentation = 0; static int is_object_interface = 0; 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_def_or_decl(FILE *f, decl_type_t *dt, int field, const char *name);
static void indent(FILE *h, int delta) { int c; if (delta < 0) indentation += delta; for (c=0; c<indentation; c++) fprintf(h, " "); if (delta > 0) indentation += delta; } @@ -64,39 +64,39 @@ static void write_line(FILE *f, int delta, const char *fmt, ...) }
int is_ptrchain_attr(const var_t *var, enum attr_type t) { if (is_attr(var->attrs, t)) return 1; else { - type_t *type = var->type; + type_t *type = var->decltype.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; } } }
int is_aliaschain_attr(const type_t *type, enum attr_type attr) { const type_t *t = type; for (;;) { 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; } }
int is_attr(const attr_list_t *list, enum attr_type t) { const attr_t *attr; if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) @@ -115,16 +115,25 @@ void *get_attrp(const attr_list_t *list, enum attr_type t) unsigned int get_attrv(const attr_list_t *list, enum attr_type t) { const attr_t *attr; if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) if (attr->type == t) return attr->u.ival; return 0; }
+decl_type_t *get_attrdt(const attr_list_t *list, enum attr_type t) +{ + const attr_t *attr; + assert(t == ATTR_WIREMARSHAL); + if (list) LIST_FOR_EACH_ENTRY( attr, list, const attr_t, entry ) + if (attr->type == t) return (decl_type_t*)&attr->u.dtval; + return NULL; +} + static void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid) { if (!uuid) return; fprintf(f, "DEFINE_GUID(%s_%s, 0x%08x, 0x%04x, 0x%04x, 0x%02x,0x%02x, 0x%02x," "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x);\n", guid_prefix, name, uuid->Data1, uuid->Data2, uuid->Data3, uuid->Data4[0], uuid->Data4[1], uuid->Data4[2], uuid->Data4[3], uuid->Data4[4], uuid->Data4[5], uuid->Data4[6], uuid->Data4[7]); @@ -199,38 +208,38 @@ static void write_fields(FILE *h, var_list_t *fields) unsigned nameless_struct_cnt = 0, nameless_struct_i = 0, nameless_union_cnt = 0, nameless_union_i = 0; const char *name; char buf[32]; var_t *v;
if (!fields) return;
LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) { - if (!v || !v->type) continue; + if (!v || !v->decltype.type) continue;
- switch(type_get_type_detect_alias(v->type)) { + switch(type_get_type_detect_alias(v->decltype.type)) { case TYPE_STRUCT: case TYPE_ENCAPSULATED_UNION: nameless_struct_cnt++; break; case TYPE_UNION: nameless_union_cnt++; break; default: ; } }
LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) { - if (!v || !v->type) continue; + if (!v || !v->decltype.type) continue;
indent(h, 0); name = v->name;
- switch(type_get_type_detect_alias(v->type)) { + switch(type_get_type_detect_alias(v->decltype.type)) { case TYPE_STRUCT: case TYPE_ENCAPSULATED_UNION: if(!v->name) { fprintf(h, "__C89_NAMELESS "); if(nameless_struct_cnt == 1) { name = "__C89_NAMELESSSTRUCTNAME"; }else if(nameless_struct_i < 5 /* # of supporting macros */) { sprintf(buf, "__C89_NAMELESSSTRUCTNAME%d", ++nameless_struct_i); @@ -247,17 +256,17 @@ static void write_fields(FILE *h, var_list_t *fields) sprintf(buf, "__C89_NAMELESSUNIONNAME%d", ++nameless_union_i); name = buf; } } break; default: ; } - write_type_def_or_decl(h, v->type, TRUE, name); + write_type_def_or_decl(h, &v->decltype, TRUE, name); fprintf(h, ";\n"); } }
static void write_enums(FILE *h, var_list_t *enums, const char *enum_name) { var_t *v; if (!enums) return; @@ -289,27 +298,29 @@ static void write_pointer_left(FILE *h, type_t *ref) { if (needs_space_after(ref)) fprintf(h, " "); if (!type_is_alias(ref) && is_array(ref) && !type_array_is_decl_as_ptr(ref)) fprintf(h, "("); fprintf(h, "*"); }
-void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly) +void write_decltype_left(FILE* h, decl_type_t *dt, enum name_type name_type, int declonly) { const char *name; + type_t *t = dt->type;
if (!h) return;
name = type_get_name(t, name_type);
- if (is_attr(t->attrs, ATTR_CONST) && - (type_is_alias(t) || !is_ptr(t))) + if ((dt->typequalifier == TYPE_QUALIFIER_CONST) && + (type_is_alias(t) || !is_ptr(t))) { fprintf(h, "const "); + }
if (type_is_alias(t)) fprintf(h, "%s", t->name); else { switch (type_get_type_detect_alias(t)) { case TYPE_ENUM: if (!declonly && t->defined && !t->written) { if (name) fprintf(h, "enum %s {\n", name); else fprintf(h, "enum {\n"); @@ -346,29 +357,33 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly) write_fields(h, type_union_get_cases(t)); indent(h, -1); fprintf(h, "}"); } else fprintf(h, "union %s", t->name ? t->name : ""); 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_decltype_left(h, type_pointer_get_ref(t), name_type, declonly); + write_pointer_left(h, type_pointer_get_ref_type(t)); + + if (dt->typequalifier == TYPE_QUALIFIER_CONST) { + fprintf(h, "const "); + } + break; } case TYPE_ARRAY: if (t->name && type_array_is_decl_as_ptr(t)) fprintf(h, "%s", t->name); else { - write_type_left(h, type_array_get_element(t), name_type, declonly); + write_decltype_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: if (type_basic_get_type(t) != TYPE_BASIC_INT32 && type_basic_get_type(t) != TYPE_BASIC_INT64 && type_basic_get_type(t) != TYPE_BASIC_LONG && type_basic_get_type(t) != TYPE_BASIC_HYPER) { @@ -418,55 +433,61 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly) case TYPE_MODULE: case TYPE_COCLASS: fprintf(h, "%s", t->name); break; case TYPE_VOID: fprintf(h, "void"); break; case TYPE_BITFIELD: - write_type_left(h, type_bitfield_get_field(t), name_type, declonly); + write_decltype_left(h, type_bitfield_get_field(t), name_type, declonly); break; case TYPE_ALIAS: case TYPE_FUNCTION: /* handled elsewhere */ assert(0); break; } } }
+void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly) +{ + decl_type_t dt; + write_decltype_left(h, init_decltype(&dt, t), name_type, declonly); +} + void write_type_right(FILE *h, type_t *t, int is_field) { if (!h) return; if (type_is_alias(t)) return;
switch (type_get_type(t)) { case TYPE_ARRAY: { - type_t *elem = type_array_get_element(t); + type_t *elemtype = 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)) + if (!type_is_alias(elemtype) && is_array(elemtype) && !type_array_is_decl_as_ptr(elemtype)) fprintf(h, ")"); } else { if (is_conformant_array(t)) fprintf(h, "[%s]", is_field ? "1" : ""); else fprintf(h, "[%u]", type_array_get_dim(t)); } - write_type_right(h, elem, FALSE); + write_type_right(h, elemtype, FALSE); break; } 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); break; } case TYPE_BITFIELD: fprintf(h, " : %u", type_bitfield_get_bits(t)->cval); break; @@ -480,40 +501,46 @@ void write_type_right(FILE *h, type_t *t, int is_field) case TYPE_MODULE: case TYPE_COCLASS: case TYPE_FUNCTION: case TYPE_INTERFACE: break; } }
-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, decl_type_t *dt, int is_field, int declonly, const char *name) { + type_t *t = dt->type; type_t *pt = NULL; + decl_type_t *dpt = NULL; int ptr_level = 0;
if (!h) return;
if (t) { - for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++) + for (dpt = dt; 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(dt->type) && dt->funcspecifier == FUNCTION_SPECIFIER_INLINE) { + fprintf(h, "inline "); + } + write_decltype_left(h, type_function_get_retdecltype(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); + } else { + write_decltype_left(h, dt, NAME_DEFAULT, declonly); + } }
if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
if (t) { if (type_get_type_detect_alias(pt) == TYPE_FUNCTION) { const var_list_t *args = type_function_get_args(pt);
@@ -524,19 +551,19 @@ static void write_type_v(FILE *h, type_t *t, int is_field, int declonly, const c else fprintf(h, "void"); fputc(')', h); } else write_type_right(h, t, is_field); } }
-static void write_type_def_or_decl(FILE *f, type_t *t, int field, const char *name) +static void write_type_def_or_decl(FILE *f, decl_type_t *dt, int field, const char *name) { - write_type_v(f, t, field, FALSE, name); + write_type_v(f, dt, field, FALSE, name); }
static void write_type_definition(FILE *f, type_t *t) { int in_namespace = t->namespace && !is_global_namespace(t->namespace); int save_written = t->written;
if(in_namespace) { @@ -555,22 +582,28 @@ static void write_type_definition(FILE *f, type_t *t) write_type_left(f, t, NAME_C, FALSE); fprintf(f, ";\n"); fprintf(f, "#endif\n\n"); } }
void write_type_decl(FILE *f, type_t *t, const char *name) { - write_type_v(f, t, FALSE, TRUE, name); + decl_type_t dt; + write_decltype_decl(f, init_decltype(&dt, t), name); }
-void write_type_decl_left(FILE *f, type_t *t) +void write_decltype_decl(FILE *f, decl_type_t *dt, const char *name) { - write_type_left(f, t, NAME_DEFAULT, TRUE); + write_type_v(f, dt, FALSE, TRUE, name); +} + +void write_decltype_decl_left(FILE *f, decl_type_t *dt) +{ + write_decltype_left(f, dt, NAME_DEFAULT, TRUE); }
static int user_type_registered(const char *name) { user_type_t *ut; LIST_FOR_EACH_ENTRY(ut, &user_type_list, user_type_t, entry) if (!strcmp(name, ut->name)) return 1; @@ -597,18 +630,18 @@ static int generic_handle_registered(const char *name)
unsigned int get_context_handle_offset( const type_t *type ) { context_handle_t *ch; unsigned int index = 0;
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 ) { if (!strcmp( type->name, ch->name )) return index; index++; } error( "internal error: %s is not registered as a context handle\n", type->name ); @@ -617,18 +650,18 @@ unsigned int get_context_handle_offset( const type_t *type )
unsigned int get_generic_handle_offset( const type_t *type ) { generic_handle_t *gh; unsigned int index = 0;
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 ) { if (!strcmp( type->name, gh->name )) return index; index++; } error( "internal error: %s is not registered as a generic handle\n", type->name ); @@ -692,25 +725,25 @@ void check_for_additional_prototype_types(type_t *type) 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->type); + check_for_additional_prototype_types(v->decltype.type); }
if (type_is_alias(type)) - type = type_alias_get_aliasee(type); + type = type_alias_get_aliasee_type(type); else if (is_ptr(type)) - type = type_pointer_get_ref(type); + type = type_pointer_get_ref_type(type); else if (is_array(type)) - type = type_array_get_element(type); + type = type_array_get_element_type(type); else break; } }
static int write_serialize_function_decl(FILE *header, const type_t *type) { write_serialize_functions(header, type, NULL); @@ -722,33 +755,33 @@ static int serializable_exists(FILE *header, const type_t *type) return 0; }
static int for_each_serializable(const statement_list_t *stmts, FILE *header, int (*proc)(FILE*, const type_t*)) { statement_t *stmt, *iface_stmt; statement_list_t *iface_stmts; - const type_list_t *type_entry; + const typedef_list_t *typedef_entry;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) { if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE) continue;
iface_stmts = type_iface_get_stmts(stmt->u.type); if (iface_stmts) LIST_FOR_EACH_ENTRY( iface_stmt, iface_stmts, statement_t, entry ) { if (iface_stmt->type != STMT_TYPEDEF) continue; - for (type_entry = iface_stmt->u.type_list; type_entry; type_entry = type_entry->next) + for (typedef_entry = iface_stmt->u.typedef_list; typedef_entry; typedef_entry = typedef_entry->next) { - if (!is_attr(type_entry->type->attrs, ATTR_ENCODE) - && !is_attr(type_entry->type->attrs, ATTR_DECODE)) + if (!is_attr(typedef_entry->var->decltype.type->attrs, ATTR_ENCODE) + && !is_attr(typedef_entry->var->decltype.type->attrs, ATTR_DECODE)) continue; - if (!proc(header, type_entry->type)) + if (!proc(header, typedef_entry->var->decltype.type)) return 0; } } }
return 1; }
@@ -790,132 +823,132 @@ static void write_typedef(FILE *header, type_t *type) { fprintf(header, "typedef "); write_type_def_or_decl(header, type_alias_get_aliasee(type), FALSE, type->name); fprintf(header, ";\n"); }
int is_const_decl(const var_t *var) { - const type_t *t; + const decl_type_t *dt; /* 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 (dt = &var->decltype; ;) { - if (is_attr(t->attrs, ATTR_CONST)) + if (dt->typequalifier == TYPE_QUALIFIER_CONST) return TRUE; - else if (is_ptr(t)) - t = type_pointer_get_ref(t); + else if (is_ptr(dt->type)) + dt = type_pointer_get_ref(dt->type); else break; } return FALSE; }
static void write_declaration(FILE *header, const var_t *v) { if (is_const_decl(v) && v->eval) { fprintf(header, "#define %s (", v->name); write_expr(header, v->eval, 0, 1, NULL, NULL, ""); fprintf(header, ")\n\n"); } else { - switch (v->stgclass) + switch (v->decltype.stgclass) { case STG_NONE: case STG_REGISTER: /* ignored */ break; case STG_STATIC: fprintf(header, "static "); break; case STG_EXTERN: fprintf(header, "extern "); break; } - write_type_def_or_decl(header, v->type, FALSE, v->name); + write_type_def_or_decl(header, (decl_type_t*)&v->decltype, FALSE, v->name); fprintf(header, ";\n\n"); } }
static void write_library(FILE *header, const typelib_t *typelib) { const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID); fprintf(header, "\n"); write_guid(header, "LIBID", typelib->name, uuid); fprintf(header, "\n"); }
const type_t* get_explicit_generic_handle_type(const var_t* var) { const type_t *t; - for (t = var->type; + for (t = var->decltype.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; return NULL; }
const var_t *get_func_handle_var( const type_t *iface, const var_t *func, unsigned char *explicit_fc, unsigned char *implicit_fc ) { const var_t *var; - const var_list_t *args = type_get_function_args( func->type ); + const var_list_t *args = type_get_function_args( func->decltype.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->decltype.type ) == TYPE_BASIC && type_basic_get_type( var->decltype.type ) == TYPE_BASIC_HANDLE) { *explicit_fc = FC_BIND_PRIMITIVE; return var; } if (get_explicit_generic_handle_type( var )) { *explicit_fc = FC_BIND_GENERIC; return var; } - if (is_context_handle( var->type )) + if (is_context_handle( var->decltype.type )) { *explicit_fc = FC_BIND_CONTEXT; return var; } }
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->decltype.type ) == TYPE_BASIC && + type_basic_get_type( var->decltype.type ) == TYPE_BASIC_HANDLE) *implicit_fc = FC_BIND_PRIMITIVE; else *implicit_fc = FC_BIND_GENERIC; return var; }
*implicit_fc = FC_AUTO_HANDLE; return NULL; }
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->decltype.type))) return 1;
- if (!type_get_function_args(func->type)) + if (!type_get_function_args(func->decltype.type)) return 0;
- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.type), const var_t, entry ) if (is_attr(var->attrs, ATTR_OUT)) return 1;
return 0; }
/********** INTERFACES **********/ @@ -985,17 +1018,17 @@ static int is_override_method(const type_t *iface, const type_t *child, const va } while ((child = type_iface_get_inherit(child)) && child != iface);
return 0; }
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->decltype.type)); return type == TYPE_STRUCT || type == TYPE_UNION || type == TYPE_COCLASS || type == TYPE_INTERFACE; }
static char *get_vtbl_entry_name(const type_t *iface, const var_t *func) { static char buff[255]; if (is_inherited_method(iface, func)) @@ -1025,30 +1058,30 @@ static void write_method_macro(FILE *header, const type_t *iface, const type_t *
if (is_override_method(iface, child, func)) continue;
if (!is_callas(func->attrs)) { const var_t *arg;
fprintf(header, "#define %s_%s(This", name, get_name(func)); - if (type_get_function_args(func->type)) - LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry ) + if (type_get_function_args(func->decltype.type)) + LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->decltype.type), const var_t, entry ) fprintf(header, ",%s", arg->name); fprintf(header, ") ");
if (is_aggregate_return(func)) { fprintf(header, "%s_%s_define_WIDL_C_INLINE_WRAPPERS_for_aggregate_return_support\n", name, get_name(func)); continue; }
fprintf(header, "(This)->lpVtbl->%s(This", get_vtbl_entry_name(iface, func)); - if (type_get_function_args(func->type)) - LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry ) + if (type_get_function_args(func->decltype.type)) + LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->decltype.type), const var_t, entry ) fprintf(header, ",%s", arg->name); fprintf(header, ")\n"); } } }
void write_args(FILE *h, const var_list_t *args, const char *name, int method, int do_indent) { @@ -1068,29 +1101,29 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i if (count) { if (do_indent) { fprintf(h, ",\n"); indent(h, 0); } else fprintf(h, ","); } - write_type_decl(h, arg->type, arg->name); + write_decltype_decl(h, (decl_type_t*)&arg->decltype, arg->name); if (method == 2) { const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE); if (expr) { const var_t *tail_arg;
/* Output default value only if all following arguments also have default value. */ LIST_FOR_EACH_ENTRY_REV( tail_arg, args, const var_t, entry ) { if(tail_arg == arg) { 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->decltype.type) == VT_BSTR && expr->type == EXPR_STRLIT) { bstr = *expr; bstr.type = EXPR_WSTRLIT; expr = &bstr; }
fprintf(h, " = "); write_expr( h, expr, 0, 1, NULL, NULL, "" ); @@ -1109,67 +1142,67 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i static void write_cpp_method_def(FILE *header, const type_t *iface) { const statement_t *stmt;
STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(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->decltype.type->attrs, ATTR_CALLCONV); + const var_list_t *args = type_get_function_args(func->decltype.type); const var_t *arg;
if (!callconv) callconv = "STDMETHODCALLTYPE";
if (is_aggregate_return(func)) { fprintf(header, "#ifdef WIDL_EXPLICIT_AGGREGATE_RETURNS\n");
indent(header, 0); fprintf(header, "virtual "); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.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_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " *__ret"); --indentation; if (args) { fprintf(header, ",\n"); write_args(header, args, iface->name, 2, TRUE); } fprintf(header, ") = 0;\n");
indent(header, 0); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " %s %s(\n", callconv, get_name(func)); write_args(header, args, iface->name, 2, TRUE); fprintf(header, ")\n"); indent(header, 0); fprintf(header, "{\n"); ++indentation; indent(header, 0); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " __ret;\n"); indent(header, 0); fprintf(header, "return *%s(&__ret", get_name(func)); if (args) LIST_FOR_EACH_ENTRY(arg, args, const var_t, entry) fprintf(header, ", %s", arg->name); fprintf(header, ");\n"); --indentation; indent(header, 0); fprintf(header, "}\n");
fprintf(header, "#else\n"); }
indent(header, 0); fprintf(header, "virtual "); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " %s %s(\n", callconv, get_name(func)); write_args(header, args, iface->name, 2, TRUE); fprintf(header, ") = 0;\n");
if (is_aggregate_return(func)) fprintf(header, "#endif\n"); fprintf(header, "\n"); } @@ -1196,35 +1229,35 @@ static void write_inline_wrappers(FILE *header, const type_t *iface, const type_
if (is_override_method(iface, child, func)) continue;
if (!is_callas(func->attrs)) { const var_t *arg;
fprintf(header, "static FORCEINLINE "); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " %s_%s(", name, get_name(func)); - write_args(header, type_get_function_args(func->type), name, 1, FALSE); + write_args(header, type_get_function_args(func->decltype.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->decltype.type)) ? "" : "return ", get_vtbl_entry_name(iface, func)); } else { indent(header, 0); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " __ret;\n"); indent(header, 0); fprintf(header, "return *This->lpVtbl->%s(This,&__ret", get_vtbl_entry_name(iface, func)); } - if (type_get_function_args(func->type)) - LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry ) + if (type_get_function_args(func->decltype.type)) + LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->decltype.type), const var_t, entry ) fprintf(header, ",%s", arg->name); fprintf(header, ");\n"); --indentation; fprintf(header, "}\n"); } } }
@@ -1240,39 +1273,39 @@ static void do_write_c_method_def(FILE *header, const type_t *iface, const char { const var_t *func = stmt->u.var; if (first_iface) { indent(header, 0); fprintf(header, "/*** %s methods ***/\n", iface->name); first_iface = 0; } if (!is_callas(func->attrs)) { - const char *callconv = get_attrp(func->type->attrs, ATTR_CALLCONV); + const char *callconv = get_attrp(func->decltype.type->attrs, ATTR_CALLCONV); if (!callconv) callconv = "STDMETHODCALLTYPE"; indent(header, 0); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); if (is_aggregate_return(func)) fprintf(header, " *"); if (is_inherited_method(iface, func)) fprintf(header, " (%s *%s_%s)(\n", callconv, iface->name, func->name); else fprintf(header, " (%s *%s)(\n", callconv, get_name(func)); ++indentation; indent(header, 0); fprintf(header, "%s *This", name); if (is_aggregate_return(func)) { fprintf(header, ",\n"); indent(header, 0); - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " *__ret"); } --indentation; - if (type_get_function_args(func->type)) { + if (type_get_function_args(func->decltype.type)) { fprintf(header, ",\n"); - write_args(header, type_get_function_args(func->type), name, 0, TRUE); + write_args(header, type_get_function_args(func->decltype.type), name, 0, TRUE); } fprintf(header, ");\n"); fprintf(header, "\n"); } } }
static void write_c_method_def(FILE *header, const type_t *iface) @@ -1289,22 +1322,22 @@ static void write_method_proto(FILE *header, const type_t *iface) { const statement_t *stmt;
STATEMENTS_FOR_EACH_FUNC(stmt, type_iface_get_stmts(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->decltype.type->attrs, ATTR_CALLCONV); if (!callconv) callconv = "STDMETHODCALLTYPE"; /* proxy prototype */ - write_type_decl_left(header, type_function_get_rettype(func->type)); + write_decltype_decl_left(header, type_function_get_retdecltype(func->decltype.type)); fprintf(header, " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); - write_args(header, type_get_function_args(func->type), iface->name, 1, TRUE); + write_args(header, type_get_function_args(func->decltype.type), iface->name, 1, TRUE); fprintf(header, ");\n"); /* stub prototype */ fprintf(header, "void __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(func)); fprintf(header, " IRpcStubBuffer* This,\n"); fprintf(header, " IRpcChannelBuffer* pRpcChannelBuffer,\n"); fprintf(header, " PRPC_MESSAGE pRpcMessage,\n"); fprintf(header, " DWORD* pdwStubPhase);\n"); } @@ -1327,41 +1360,41 @@ static void write_locals(FILE *fp, const type_t *iface, int body) if (cas) { const statement_t *stmt2 = NULL; STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) if (!strcmp(get_name(stmt2->u.var), cas->name)) break; 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_decltype_decl_left(fp, type_function_get_retdecltype(m->decltype.type)); fprintf(fp, " CALLBACK %s_%s_Proxy(\n", iface->name, get_name(m)); - write_args(fp, type_get_function_args(m->type), iface->name, 1, TRUE); + write_args(fp, type_get_function_args(m->decltype.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->decltype.type); fprintf(fp, "\n{\n"); fprintf(fp, " %s\n", comment); if (rt->name && strcmp(rt->name, "HRESULT") == 0) fprintf(fp, " return E_NOTIMPL;\n"); else if (type_get_type(rt) != TYPE_VOID) { fprintf(fp, " "); write_type_decl(fp, rt, "rv"); fprintf(fp, ";\n"); fprintf(fp, " memset(&rv, 0, sizeof rv);\n"); fprintf(fp, " return rv;\n"); } fprintf(fp, "}\n\n"); } else fprintf(fp, ";\n"); /* stub prototype - use remotable prototype */ - write_type_decl_left(fp, type_function_get_rettype(func->type)); + write_decltype_decl_left(fp, type_function_get_retdecltype(func->decltype.type)); fprintf(fp, " __RPC_STUB %s_%s_Stub(\n", iface->name, get_name(m)); - write_args(fp, type_get_function_args(func->type), iface->name, 1, TRUE); + write_args(fp, type_get_function_args(func->decltype.type), iface->name, 1, TRUE); fprintf(fp, ")"); if (body) /* Remotable methods must all return HRESULTs. */ fprintf(fp, "\n{\n %s\n return E_NOTIMPL;\n}\n\n", comment); else fprintf(fp, ";\n"); } else @@ -1397,25 +1430,28 @@ void write_local_stubs(const statement_list_t *stmts)
write_local_stubs_stmts(local_stubs, stmts);
fclose(local_stubs); }
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->decltype.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_decltype_decl_left(header, type_function_get_retdecltype(fun->decltype.type)); + if (fun->decltype.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_get_function_args(fun->decltype.type)) + write_args(header, type_get_function_args(fun->decltype.type), iface->name, 0, TRUE); else fprintf(header, " void"); fprintf(header, ");\n\n"); }
static void write_forward(FILE *header, type_t *iface) { fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", iface->c_name); @@ -1531,17 +1567,17 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface) fprintf(header, "/*****************************************************************************\n"); fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver)); fprintf(header, " */\n"); fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name); fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name); if (var) { fprintf(header, "extern "); - write_type_decl( header, var->type, var->name ); + write_decltype_decl( header, (decl_type_t*)&var->decltype, var->name ); fprintf(header, ";\n"); } if (old_names) { fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name); fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name); } else @@ -1727,30 +1763,30 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons case STMT_PRAGMA: /* not included in header */ break; case STMT_IMPORT: /* not processed here */ break; case STMT_TYPEDEF: { - const type_list_t *type_entry = stmt->u.type_list; - for (; type_entry; type_entry = type_entry->next) - write_typedef(header, type_entry->type); + const typedef_list_t *typedef_entry = stmt->u.typedef_list; + for (; typedef_entry; typedef_entry = typedef_entry->next) + write_typedef(header, typedef_entry->var->decltype.type); break; } case STMT_LIBRARY: write_library(header, stmt->u.lib); write_header_stmts(header, stmt->u.lib->stmts, NULL, FALSE); break; case STMT_CPPQUOTE: 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->decltype.type) == TYPE_FUNCTION) { if (!ignore_funcs) { int prefixes_differ = strcmp(prefix_client, prefix_server);
if (prefixes_differ) { fprintf(header, "/* client prototype */\n"); diff --git a/tools/widl/header.h b/tools/widl/header.h index 0d44b4039f..5a7359c7ac 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -23,21 +23,24 @@
#include "typetree.h"
extern int is_ptrchain_attr(const var_t *var, enum attr_type t); extern int is_aliaschain_attr(const type_t *var, enum attr_type t); 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 decl_type_t *get_attrdt(const attr_list_t *list, enum attr_type t); extern const char* get_name(const var_t *v); +extern void write_decltype_left(FILE *h, decl_type_t *dt, 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_decltype_decl(FILE *f, decl_type_t *dt, const char *name);\ +extern void write_decltype_decl_left(FILE *f, decl_type_t *dt); 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); extern int is_object(const type_t *iface); extern int is_local(const attr_list_t *list); extern int count_methods(const type_t *iface); extern int need_stub(const type_t *iface); extern int need_proxy(const type_t *iface); @@ -78,34 +81,34 @@ static inline int is_declptr(const type_t *t)
static inline int is_conformant_array(const type_t *t) { return is_array(t) && type_array_has_conformance(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) { return ((is_attr(attrs, ATTR_STRING) || is_aliaschain_attr(type, ATTR_STRING)) && (last_ptr(type) || last_array(type))); }
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; }
#endif diff --git a/tools/widl/parser.y b/tools/widl/parser.y index dd676e9a28..2bffdbab41 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -47,50 +47,45 @@ struct typenode { };
struct _import_t { char *name; 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); 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_type_t *make_decl_type(type_t *type, decl_type_t *left, decl_type_t *right, attr_t *attr, enum storage_class stgclass); +static decl_type_t *make_decl_type2(type_t *type, decl_type_t *left, decl_type_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); +static attr_t *make_attrdt(enum attr_type type, type_t *val); static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); static type_t *append_array(type_t *chain, expr_t *expr); -static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top); -static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls); +static var_t *declare_var(attr_list_t *attrs, const decl_type_t *decltype, const declarator_t *decl, int top); +static var_list_t *set_var_types(attr_list_t *attrs, decl_type_t *decltype, declarator_list_t *decls); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_t *make_ifref(type_t *iface); static var_list_t *append_var_list(var_list_t *list, var_list_t *vars); static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p); 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 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); +static type_t *reg_typedefs(decl_type_t *decltype, var_list_t *names, attr_list_t *attrs); static type_t *find_type_or_error(const char *name, int t); static type_t *find_type_or_error2(char *name, int t);
static var_t *reg_const(var_t *var);
static void push_namespace(const char *name); static void pop_namespace(const char *name);
@@ -158,17 +153,17 @@ static typelib_t *current_typelib; ifref_list_t *ifref_list; char *str; UUID *uuid; unsigned int num; double dbl; interface_info_t ifinfo; typelib_t *typelib; struct _import_t *import; - struct _decl_spec_t *declspec; + struct _decl_type_t *decltype; enum storage_class stgclass; }
%token <str> aIDENTIFIER aPRAGMA %token <str> aKNOWNTYPE %token <num> aNUM aHEXNUM %token <dbl> aDOUBLE %token <str> aSTRING aWSTRING aSQSTRING @@ -269,17 +264,17 @@ static typelib_t *current_typelib; %type <attr> attribute type_qualifier function_specifier acf_attribute %type <attr_list> m_attributes attributes attrib_list m_type_qual_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 <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type +%type <decltype> decl_spec decl_spec_no_type m_decl_spec_no_type %type <type> inherit interface interfacedef interfacedec %type <type> dispinterface dispinterfacehdr dispinterfacedef %type <type> module modulehdr moduledef %type <str> namespacedef %type <type> base_type int_std %type <type> enumdef structdef uniondef typedecl %type <type> type %type <ifref> coclass_int @@ -592,17 +587,17 @@ attribute: { $$ = NULL; } | tUSESGETLASTERROR { $$ = make_attr(ATTR_USESGETLASTERROR); } | tUSERMARSHAL '(' type ')' { $$ = make_attrp(ATTR_USERMARSHAL, $3); } | tUUID '(' uuid_string ')' { $$ = make_attrp(ATTR_UUID, $3); } | tASYNCUUID '(' uuid_string ')' { $$ = make_attrp(ATTR_ASYNCUUID, $3); } | tV1ENUM { $$ = make_attr(ATTR_V1ENUM); } | tVARARG { $$ = make_attr(ATTR_VARARG); } | tVERSION '(' version ')' { $$ = make_attrv(ATTR_VERSION, $3); } | tVIPROGID '(' aSTRING ')' { $$ = make_attrp(ATTR_VIPROGID, $3); } - | tWIREMARSHAL '(' type ')' { $$ = make_attrp(ATTR_WIREMARSHAL, $3); } + | tWIREMARSHAL '(' type ')' { $$ = make_attrdt(ATTR_WIREMARSHAL, $3); } | pointer_type { $$ = make_attrv(ATTR_POINTERTYPE, $1); } ;
uuid_string: aUUID | aSTRING { if (!is_valid_uuid($1)) error_loc("invalid UUID: %s\n", $1); $$ = parse_uuid($1); } @@ -646,20 +641,20 @@ enum_list: enum { if (!$1->eval) $3->eval = make_exprl(type, last->eval->cval + 1); } $$ = append_var( $1, $3 ); } ;
enum: ident '=' expr_int_const { $$ = reg_const($1); $$->eval = $3; - $$->type = type_new_int(TYPE_BASIC_INT, 0); + $$->decltype.type = type_new_int(TYPE_BASIC_INT, 0); } | ident { $$ = reg_const($1); - $$->type = type_new_int(TYPE_BASIC_INT, 0); + $$->decltype.type = type_new_int(TYPE_BASIC_INT, 0); } ;
enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, current_namespace, TRUE, $4); } ;
m_exprs: m_expr { $$ = append_expr( NULL, $1 ); } | m_exprs ',' m_expr { $$ = append_expr( $1, $3 ); } @@ -735,17 +730,17 @@ fields: { $$ = NULL; } ;
field: m_attributes decl_spec struct_declarator_list ';' { const char *first = LIST_ENTRY(list_head($3), declarator_t, entry)->var->name; check_field_attrs(first, $1); $$ = set_var_types($1, $2, $3); } | m_attributes uniondef ';' { var_t *v = make_var(NULL); - v->type = $2; v->attrs = $1; + v->decltype.type = $2; v->attrs = $1; $$ = append_var(NULL, v); } ;
ne_union_field: s_field ';' { $$ = $1; } | attributes ';' { $$ = make_var(NULL); $$->attrs = $1; } ; @@ -759,23 +754,23 @@ union_field: | ';' { $$ = NULL; } ;
s_field: m_attributes decl_spec declarator { $$ = declare_var(check_field_attrs($3->var->name, $1), $2, $3, FALSE); free($3); } | m_attributes structdef { var_t *v = make_var(NULL); - v->type = $2; v->attrs = $1; + v->decltype.type = $2; v->attrs = $1; $$ = v; } ;
funcdef: declaration { $$ = $1; - if (type_get_type($$->type) != TYPE_FUNCTION) + if (type_get_type($$->decltype.type) != TYPE_FUNCTION) error_loc("only methods may be declared inside the methods section of a dispinterface\n"); check_function_attrs($$->name, $$->attrs); } ;
declaration: attributes decl_spec init_declarator { $$ = declare_var($1, $2, $3, FALSE); @@ -961,29 +956,29 @@ function_specifier: type_qualifier: tCONST { $$ = make_attr(ATTR_CONST); } ;
m_type_qual_list: { $$ = NULL; } | m_type_qual_list type_qualifier { $$ = append_attr($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_type($1, $2, NULL, NULL, STG_NONE); } | decl_spec_no_type type m_decl_spec_no_type - { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); } + { $$ = make_decl_type($2, $1, $3, NULL, STG_NONE); } ;
m_decl_spec_no_type: { $$ = NULL; } | decl_spec_no_type ;
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_type(NULL, $2, NULL, $1, STG_NONE); } + | function_specifier m_decl_spec_no_type { $$ = make_decl_type(NULL, $2, NULL, $1, STG_NONE); } + | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_type(NULL, $2, NULL, NULL, $1); } ;
declarator: '*' m_type_qual_list declarator %prec PPTR { $$ = $3; $$->type = append_chain_type($$->type, 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)); } | direct_declarator @@ -1192,17 +1187,18 @@ acf_attribute static void decl_builtin_basic(const char *name, enum type_basic_type type) { type_t *t = type_new_basic(type); reg_type(t, name, NULL, 0); }
static void decl_builtin_alias(const char *name, type_t *t) { - reg_type(type_new_alias(t, name), name, NULL, 0); + decl_type_t decltype; + reg_type(type_new_alias(init_decltype(&decltype, t), name, &global_namespace), name, &global_namespace, 0); }
void init_types(void) { decl_builtin_basic("byte", TYPE_BASIC_BYTE); decl_builtin_basic("wchar_t", TYPE_BASIC_WCHAR); decl_builtin_basic("float", TYPE_BASIC_FLOAT); decl_builtin_basic("double", TYPE_BASIC_DOUBLE); @@ -1256,16 +1252,28 @@ static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type if (attr->type == type) { list_remove(&attr->entry); return append_attr(dst, attr); } return dst; }
+ +static attr_list_t *remove_attr(attr_list_t *lst, enum attr_type type) +{ + attr_t *attr; + LIST_FOR_EACH_ENTRY(attr, lst, attr_t, entry) + if (attr->type == type) + { + list_remove(&attr->entry); + } + return lst; +} + static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list) { struct list *entry;
if (!old_list) return new_list;
while ((entry = list_head(old_list))) { @@ -1293,65 +1301,104 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter if (filter && !filter(new_list, attr)) continue; new_attr = xmalloc(sizeof(*new_attr)); *new_attr = *attr; list_add_tail(new_list, &new_attr->entry); } 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_type_t *make_decl_type(type_t *type, decl_type_t *left, decl_type_t *right, attr_t *attr, enum storage_class stgclass) { - decl_spec_t *declspec = left ? left : right; - if (!declspec) + enum type_qualifier typequalifier = TYPE_QUALIFIER_NONE; + enum function_specifier funcspecifier = FUNCTION_SPECIFIER_NONE; + + assert(attr == NULL || attr->type == ATTR_CONST || attr->type == ATTR_INLINE); + + if (attr != NULL) { - declspec = xmalloc(sizeof(*declspec)); - declspec->type = NULL; - declspec->attrs = NULL; - declspec->stgclass = STG_NONE; + if (attr->type == ATTR_CONST) + typequalifier = TYPE_QUALIFIER_CONST; + else if (attr->type == ATTR_INLINE) + funcspecifier = FUNCTION_SPECIFIER_INLINE; } - declspec->type = type; - if (left && declspec != left) + + return make_decl_type2(type, left, right, stgclass, typequalifier, funcspecifier); +} + +static decl_type_t *make_decl_type2(type_t *type, decl_type_t *left, decl_type_t *right, enum storage_class stgclass, enum type_qualifier typequalifier, enum function_specifier funcspecifier) +{ + decl_type_t *decltype = left ? left : right; + + if (!decltype) + { + decltype = xmalloc(sizeof(*decltype)); + decltype->type = NULL; + decltype->stgclass = STG_NONE; + decltype->typequalifier = TYPE_QUALIFIER_NONE; + decltype->funcspecifier = FUNCTION_SPECIFIER_NONE; + } + decltype->type = type; + if (left && decltype != left) { - declspec->attrs = append_attr_list(declspec->attrs, left->attrs); - if (declspec->stgclass == STG_NONE) - declspec->stgclass = left->stgclass; + if (decltype->stgclass == STG_NONE) + decltype->stgclass = left->stgclass; else if (left->stgclass != STG_NONE) error_loc("only one storage class can be specified\n"); + + if (decltype->typequalifier == TYPE_QUALIFIER_NONE) + decltype->typequalifier = left->typequalifier; + else if (left->typequalifier != TYPE_QUALIFIER_NONE) + error_loc("only one type qualifier can be specified\n"); + + if (decltype->funcspecifier == FUNCTION_SPECIFIER_NONE) + decltype->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) + if (right && decltype != right) { - declspec->attrs = append_attr_list(declspec->attrs, right->attrs); - if (declspec->stgclass == STG_NONE) - declspec->stgclass = right->stgclass; + if (decltype->stgclass == STG_NONE) + decltype->stgclass = right->stgclass; else if (right->stgclass != STG_NONE) error_loc("only one storage class can be specified\n"); + + if (decltype->typequalifier == TYPE_QUALIFIER_NONE) + decltype->typequalifier = right->typequalifier; + else if (right->typequalifier != TYPE_QUALIFIER_NONE) + error_loc("only one type qualifier can be specified\n"); + + if (decltype->funcspecifier == FUNCTION_SPECIFIER_NONE) + decltype->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; + if (decltype->stgclass == STG_NONE) + decltype->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 (decltype->typequalifier == TYPE_QUALIFIER_NONE) + decltype->typequalifier = typequalifier; + else if (typequalifier != TYPE_QUALIFIER_NONE) + error_loc("only one type qualifier can be specified\n"); + + if (decltype->funcspecifier == FUNCTION_SPECIFIER_NONE) + decltype->funcspecifier = funcspecifier; + else if (funcspecifier != FUNCTION_SPECIFIER_NONE) + error_loc("only one function specifier can be specified\n");
- return declspec; + return decltype; }
static attr_t *make_attr(enum attr_type type) { attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.ival = 0; return a; @@ -1368,16 +1415,27 @@ static attr_t *make_attrv(enum attr_type type, unsigned int val) static attr_t *make_attrp(enum attr_type type, void *val) { attr_t *a = xmalloc(sizeof(attr_t)); a->type = type; a->u.pval = val; return a; }
+static attr_t *make_attrdt(enum attr_type type, type_t *val) +{ + attr_t *a = NULL; + assert(type == ATTR_WIREMARSHAL); + a = xmalloc(sizeof(attr_t)); + + a->type = type; + init_decltype(&a->u.dtval, val); + return a; +} + static expr_list_t *append_expr(expr_list_t *list, expr_t *expr) { if (!expr) return list; if (!list) { list = xmalloc( sizeof(*list) ); list_init( list ); } @@ -1469,38 +1527,47 @@ static int is_allowed_range_type(const type_t *type) default: return FALSE; } }
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; + decl_type_t *chain_decltype = 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)) ;
if (is_ptr(chain_type)) - chain_type->details.pointer.ref = type; + chain_decltype = &chain_type->details.pointer.ref; else if (is_array(chain_type)) - chain_type->details.array.elem = type; + chain_decltype = &chain_type->details.array.elem; else assert(0);
+ chain_decltype->type = type; + /* we need to move the ATTR_CONST attribute off the type of the pointee and onto its decltype + * typequalifier on the pointer */ + if (is_attr(type->attrs, ATTR_CONST)) { + type->attrs = remove_attr(type->attrs, ATTR_CONST); + chain_decltype->typequalifier = TYPE_QUALIFIER_CONST; + } + return chain; }
static warning_list_t *append_warning(warning_list_t *list, int num) { warning_t *entry;
if(!list) @@ -1509,152 +1576,175 @@ static warning_list_t *append_warning(warning_list_t *list, int num) list_init( list ); } entry = xmalloc( sizeof(*entry) ); entry->num = num; list_add_tail( list, &entry->entry ); 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, const decl_type_t *decltype, const declarator_t *decl, int top) { var_t *v = decl->var; expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS); expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS); expr_t *dim; type_t **ptype; type_t *func_type = decl ? decl->func_type : NULL; - type_t *type = decl_spec->type; + type_t *type = decltype->type;
- if (is_attr(type->attrs, ATTR_INLINE)) - { + + if (decltype->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->decltype.funcspecifier = decltype->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 decltype + * unless the pointee already has const type qualifier*/ + + /* we need to shuffle aroundand tranlate between TYPE_QUALIFEIR_CONST and ATTR_CONST + * in this block */ + if (!decl) + { + /* simplest case, no pointers to deal with here */ + v->decltype.typequalifier = decltype->typequalifier; + } else if (decl->bits) { + /* dealing with a bitfield, just pass it on */ + v->decltype.type = type_new_bitfield(decltype, decl->bits); + } + else { + /* here we're dealing with a pointerish type chain, so we need to pull + * the typequalifier off of the decltype and stick them in the type's attr list + */ + if (decltype->typequalifier == TYPE_QUALIFIER_CONST) { + type->attrs = append_attr(type->attrs, make_attr(ATTR_CONST)); + assert(is_attr(type->attrs, ATTR_CONST)); + } + + v->decltype.type = append_chain_type(decl->type, type); + /* finally pull the ATTR_CONST attribute off the head of the pointerish type chain, + * and stick on the var's decltype */ + if (is_attr(v->decltype.type->attrs, ATTR_CONST)) { + v->decltype.type->attrs = remove_attr(v->decltype.type->attrs, ATTR_CONST); + v->decltype.typequalifier = TYPE_QUALIFIER_CONST; + } + } + + v->decltype.stgclass = decltype->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->decltype.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->decltype.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) - { - /* 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); } } else if (ptr_attr) error_loc("%s: pointer attribute applied to non-pointer type\n", v->name); }
if (is_attr(v->attrs, ATTR_STRING)) { type_t *t = type;
- if (!is_ptr(v->type) && !is_array(v->type)) + if (!is_ptr(v->decltype.type) && !is_array(v->decltype.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; }
if (type_get_type(t) != TYPE_BASIC && (get_basic_fc(t) != FC_CHAR && get_basic_fc(t) != FC_BYTE && get_basic_fc(t) != FC_WCHAR)) { error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", v->name); } }
if (is_attr(v->attrs, ATTR_V1ENUM)) { - if (type_get_type_detect_alias(v->type) != TYPE_ENUM) + if (type_get_type_detect_alias(v->decltype.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->decltype.type)) error_loc("'%s': [range] attribute applied to non-integer type\n", v->name);
- ptype = &v->type; + ptype = &v->decltype.type; if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) { if (dim->type != EXPR_VOID) { if (is_array(*ptype)) { if (!type_array_get_conformance(*ptype) || type_array_get_conformance(*ptype)->type != EXPR_VOID) error_loc("%s: cannot specify size_is for an already sized array\n", v->name); else *ptype = type_new_array((*ptype)->name, type_array_get_element(*ptype), FALSE, 0, dim, NULL, 0); } else if (is_ptr(*ptype)) + { *ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE, 0, dim, NULL, pointer_default); + } else error_loc("%s: size_is attribute applied to illegal type\n", v->name); }
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->decltype.type; if (lengs) LIST_FOR_EACH_ENTRY(dim, lengs, expr_t, entry) { if (dim->type != EXPR_VOID) { if (is_array(*ptype)) { *ptype = type_new_array((*ptype)->name, type_array_get_element(*ptype), @@ -1663,67 +1753,69 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl type_array_get_conformance(*ptype), dim, type_array_get_ptr_default_fc(*ptype)); } else error_loc("%s: length_is attribute applied to illegal type\n", v->name); }
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); }
/* v->type is currently pointing to the type on the left-side of the * declaration, so we need to fix this up so that it is the return type of the * function and make v->type point to the function side of the declaration */ 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->decltype.type; + enum type_qualifier typequalifier = v->decltype.typequalifier; + + v->decltype.type = func_type; + v->decltype.typequalifier = TYPE_QUALIFIER_NONE; + for (ft = v->decltype.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->decltype.type = return_type; + ft->details.function->retval->decltype.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->decltype.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->decltype.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; }
-static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls) +static var_list_t *set_var_types(attr_list_t *attrs, decl_type_t *decltype, declarator_list_t *decls) { declarator_t *decl, *next; var_list_t *var_list = NULL;
LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry ) { - var_t *var = declare_var(attrs, decl_spec, decl, 0); + var_t *var = declare_var(attrs, decltype, decl, 0); var_list = append_var(var_list, var); free(decl); } - free(decl_spec); + free(decltype); return var_list; }
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface) { if (!iface) return list; if (!list) { @@ -1765,32 +1857,33 @@ static var_list_t *append_var_list(var_list_t *list, var_list_t *vars) list_move_tail( list, vars ); return list; }
var_t *make_var(char *name) { var_t *v = xmalloc(sizeof(var_t)); v->name = name; - v->type = NULL; + v->decltype.type = NULL; + v->decltype.stgclass = STG_NONE; + v->decltype.typequalifier = TYPE_QUALIFIER_NONE; + v->decltype.funcspecifier = FUNCTION_SPECIFIER_NONE; v->attrs = NULL; v->eval = NULL; - v->stgclass = STG_NONE; init_loc_info(&v->loc_info); return v; }
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->decltype = src->decltype; v->attrs = map_attrs(src->attrs, attr_filter); v->eval = src->eval; - v->stgclass = src->stgclass; v->loc_info = src->loc_info; return v; }
static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *d) { if (!d) return list; if (!list) { @@ -1808,17 +1901,26 @@ static declarator_t *make_declarator(var_t *var) d->type = NULL; d->func_type = NULL; d->bits = NULL; return d; }
static type_t *make_safearray(type_t *type) { - return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0, + decl_type_t aliasee_dt; + decl_type_t element_dt; + + init_decltype(&element_dt, + type_new_alias( + init_decltype(&aliasee_dt, type), + "SAFEARRAY", + &global_namespace)); + + return type_new_array(NULL, &element_dt, TRUE, 0, NULL, NULL, FC_RP); }
static typelib_t *make_library(const char *name, const attr_list_t *attrs) { typelib_t *typelib = xmalloc(sizeof(*typelib)); typelib->name = xstrdup(name); typelib->attrs = attrs; @@ -1921,17 +2023,17 @@ void add_incomplete(type_t *t) struct typenode *tn = xmalloc(sizeof *tn); 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); + type_t *ot = type_alias_get_aliasee_type(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; t->defined = ot->defined; } } @@ -1957,20 +2059,20 @@ static void fix_incomplete_types(type_t *complete_type) { tn->type->details.structure = complete_type->details.structure; list_remove(&tn->entry); free(tn); } } }
-static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs) +static type_t *reg_typedefs(decl_type_t *decltype, declarator_list_t *decls, attr_list_t *attrs) { const declarator_t *decl; - type_t *type = decl_spec->type; + type_t *type = decltype->type;
if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC)) attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
/* We must generate names for tagless enum, struct or union. Typedef-ing a tagless enum, struct or union means we want the typedef to be included in a library hence the public attribute. */ if (type_get_type_detect_alias(type) == TYPE_ENUM || @@ -2004,18 +2106,18 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at * FIXME: We may consider string separated type tables for each input * for cleaner solution. */ if (cur && input_name == cur->loc_info.input_name) error_loc("%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); + name = declare_var(attrs, decltype, decl, 0); + cur = type_new_alias(&name->decltype, name->name, current_namespace); cur->attrs = attrs;
if (is_incomplete(cur)) add_incomplete(cur); reg_type(cur, cur->name, current_namespace, 0); } } return type; @@ -2280,20 +2382,20 @@ static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs) LIST_FOR_EACH_ENTRY(attr, attrs, const attr_t, entry) { if (!allowed_attr[attr->type].on_interface) error_loc("inapplicable attribute %s for interface %s\n", allowed_attr[attr->type].display_name, name); 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->decltype.type) == TYPE_BASIC && + type_basic_get_type( var->decltype.type ) == TYPE_BASIC_HANDLE) continue; - if (is_aliaschain_attr( var->type, ATTR_HANDLE )) + if (is_aliaschain_attr( var->decltype.type, ATTR_HANDLE )) continue; error_loc("attribute %s requires a handle type in interface %s\n", allowed_attr[attr->type].display_name, name); } } return attrs; }
@@ -2488,17 +2590,17 @@ static int is_allowed_conf_type(const type_t *type)
static int is_ptr_guid_type(const type_t *type) { /* first, make sure it is a pointer to something */ if (!is_ptr(type)) return FALSE;
/* 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) { expr_t *dim; struct expr_loc expr_loc; expr_loc.v = arg; expr_loc.attr = attr_name; @@ -2515,17 +2617,17 @@ static void check_conformance_expr_list(const char *attr_name, const var_t *arg, }
static void check_remoting_fields(const var_t *var, type_t *type);
/* checks that properties common to fields and arguments are consistent */ 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->decltype.type; int more_to_do; const char *container_type_name; const char *var_type;
switch (type_get_type(container_type)) { case TYPE_STRUCT: container_type_name = "struct"; @@ -2545,17 +2647,17 @@ static void check_field_common(const type_t *container_type, break; default: /* should be no other container types */ assert(0); return; }
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->decltype.type, ATTR_STRING))) error_loc_info(&arg->loc_info, "string and length_is specified for argument %s are mutually exclusive attributes\n", arg->name);
if (is_attr(arg->attrs, ATTR_SIZEIS)) { expr_list_t *size_is_exprs = get_attrp(arg->attrs, ATTR_SIZEIS); check_conformance_expr_list("size_is", arg, container_type, size_is_exprs); @@ -2642,27 +2744,27 @@ static void check_field_common(const type_t *container_type, "%s '%s' of %s '%s' cannot be a context handle\n", var_type, arg->name, container_type_name, container_name); break; case TGT_STRING: { 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_USER_TYPE: case TGT_IFACE_POINTER: case TGT_BASIC: case TGT_ENUM: case TGT_RANGE: /* nothing to do */ @@ -2689,28 +2791,28 @@ static void check_remoting_fields(const var_t *var, type_t *type) fields = type_struct_get_fields(type); else error_loc_info(&var->loc_info, "undefined type declaration %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 (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) - if (field->type) check_field_common(type, type->name, field); + if (field->decltype.type) check_field_common(type, type->name, field); }
/* checks that arguments for a function make sense for marshalling and unmarshalling */ static void check_remoting_args(const var_t *func) { const char *funcname = func->name; const var_t *arg;
- if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry ) + if (func->decltype.type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->decltype.type->details.function->args, const var_t, entry ) { - const type_t *type = arg->type; + const type_t *type = arg->decltype.type;
/* check that [out] parameters have enough pointer levels */ if (is_attr(arg->attrs, ATTR_OUT)) { switch (typegen_detect_type(type, arg->attrs, TDT_ALL_TYPES)) { case TGT_BASIC: case TGT_ENUM: @@ -2740,44 +2842,44 @@ static void check_remoting_args(const var_t *func) case TGT_CTXT_HANDLE_POINTER: case TGT_POINTER: case TGT_ARRAY: /* OK */ break; } }
- check_field_common(func->type, funcname, arg); + check_field_common(func->decltype.type, funcname, arg); }
- if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID) + if (type_get_type(type_function_get_rettype(func->decltype.type)) != TYPE_VOID) { var_t var; var = *func; - var.type = type_function_get_rettype(func->type); + var.decltype.type = type_function_get_rettype(func->decltype.type); var.name = xstrdup("return value"); - check_field_common(func->type, funcname, &var); + check_field_common(func->decltype.type, funcname, &var); free(var.name); } }
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func) { unsigned char explicit_fc, implicit_fc;
/* check for a defined binding handle */ if (!get_func_handle_var( iface, func, &explicit_fc, &implicit_fc ) || !explicit_fc) { /* no explicit handle specified so add * "[in] handle_t IDL_handle" as the first parameter to the * 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->decltype.type = find_type_or_error("handle_t", 0); + type_function_add_head_arg(func->decltype.type, idl_handle); } }
static void check_functions(const type_t *iface, int is_inside_library) { const statement_t *stmt; if (is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE)) { @@ -2848,35 +2950,35 @@ static void check_async_uuid(type_t *iface) async_iface = get_type(TYPE_INTERFACE, concat_str("Async", iface->name), iface->namespace, 0); async_iface->attrs = map_attrs(iface->attrs, async_iface_attrs);
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) { var_t *begin_func, *finish_func, *func = stmt->u.var, *arg; var_list_t *begin_args = NULL, *finish_args = NULL, *args;
- args = func->type->details.function->args; + args = func->decltype.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)) begin_args = append_var(begin_args, copy_var(arg, strdup(arg->name), arg_in_attrs)); if (is_attr(arg->attrs, ATTR_OUT)) finish_args = append_var(finish_args, copy_var(arg, strdup(arg->name), arg_out_attrs)); }
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->decltype.type = type_new_function(begin_args); + begin_func->decltype.type->attrs = func->attrs; + begin_func->decltype.type->details.function->retval = func->decltype.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->decltype.type = type_new_function(finish_args); + finish_func->decltype.type->attrs = func->attrs; + finish_func->decltype.type->details.function->retval = func->decltype.type->details.function->retval; stmts = append_statement(stmts, make_statement_declaration(finish_func)); }
type_interface_define(async_iface, inherit, stmts); iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface; }
static void check_statements(const statement_list_t *stmts, int is_inside_library) @@ -2918,20 +3020,20 @@ static void check_all_user_types(const statement_list_t *stmts) if (stmt->type == STMT_LIBRARY) check_all_user_types(stmt->u.lib->stmts); else if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE && !is_local(stmt->u.type->attrs)) { const statement_t *stmt_func; STATEMENTS_FOR_EACH_FUNC(stmt_func, type_iface_get_stmts(stmt->u.type)) { const var_t *func = stmt_func->u.var; - if (func->type->details.function->args) - LIST_FOR_EACH_ENTRY( v, func->type->details.function->args, const var_t, entry ) - check_for_additional_prototype_types(v->type); - check_for_additional_prototype_types(type_function_get_rettype(func->type)); + if (func->decltype.type->details.function->args) + LIST_FOR_EACH_ENTRY( v, func->decltype.type->details.function->args, const var_t, entry ) + check_for_additional_prototype_types(v->decltype.type); + check_for_additional_prototype_types(type_function_get_rettype(func->decltype.type)); } } } }
int is_valid_uuid(const char *s) { int i; @@ -2969,26 +3071,26 @@ static statement_t *make_statement_reference(type_t *type) stmt->u.type = type; return stmt; }
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->decltype.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->decltype.type) == TYPE_FUNCTION) check_function_attrs(var->name, var->attrs); - else if (var->stgclass == STG_NONE || var->stgclass == STG_REGISTER) + else if (var->decltype.stgclass == STG_NONE || var->decltype.stgclass == STG_REGISTER) error_loc("instantiation of data is illegal\n"); return stmt; }
static statement_t *make_statement_library(typelib_t *typelib) { statement_t *stmt = make_statement(STMT_LIBRARY); stmt->u.lib = typelib; @@ -3029,35 +3131,38 @@ static statement_t *make_statement_module(type_t *type) stmt->u.type = type; return stmt; }
static statement_t *make_statement_typedef(declarator_list_t *decls) { declarator_t *decl, *next; statement_t *stmt; - type_list_t **type_list; + typedef_list_t **typedef_list;
if (!decls) return NULL;
stmt = make_statement(STMT_TYPEDEF); - stmt->u.type_list = NULL; - type_list = &stmt->u.type_list; + stmt->u.typedef_list = NULL; + typedef_list = &stmt->u.typedef_list;
LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry ) { var_t *var = decl->var; type_t *type = find_type_or_error(var->name, 0); - *type_list = xmalloc(sizeof(type_list_t)); - (*type_list)->type = type; - (*type_list)->next = NULL; + var->decltype.type = type; + + assert(var->decltype.type->is_alias); + + *typedef_list = xmalloc(sizeof(typedef_list_t)); + (*typedef_list)->var = var; + (*typedef_list)->next = NULL;
- type_list = &(*type_list)->next; + typedef_list = &(*typedef_list)->next; free(decl); - free(var); }
return stmt; }
static statement_list_t *append_statements(statement_list_t *l1, statement_list_t *l2) { if (!l2) return l1; diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 8d0e8b2cc5..65061ad510 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -100,25 +100,25 @@ static void clear_output_vars( const var_list_t *args ) { const var_t *arg;
if (!args) return; LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) { 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->decltype.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->decltype.type)) == TYPE_BASIC) continue; + if (type_get_type(type_pointer_get_ref_type(arg->decltype.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->decltype.type) && type_array_has_conformance(arg->decltype.type)) { - write_expr( proxy, type_array_get_conformance(arg->type), 1, 1, NULL, NULL, "" ); + write_expr( proxy, type_array_get_conformance(arg->decltype.type), 1, 1, NULL, NULL, "" ); fprintf( proxy, " * " ); } fprintf( proxy, "sizeof( *%s ));\n", arg->name ); } }
static int need_delegation(const type_t *iface) { @@ -142,17 +142,17 @@ static int get_delegation_indirect(const type_t *iface, const type_t ** delegate static int need_delegation_indirect(const type_t *iface) { return get_delegation_indirect(iface, NULL); }
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->decltype.type;
write_parameter_conf_or_var_exprs(proxy, indent, local_var_prefix, PHASE_FREE, arg, FALSE);
switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS)) { case TGT_ENUM: case TGT_BASIC: break; @@ -186,72 +186,72 @@ static void proxy_free_variables( var_list_t *args, const char *local_var_prefix free_variable( arg, local_var_prefix ); fprintf(proxy, "\n"); } }
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->decltype.type); + int has_ret = !is_void(retval->decltype.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->decltype.type->attrs, ATTR_CALLCONV); + const var_list_t *args = type_get_function_args(func->decltype.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_decltype_decl_left(proxy, &retval->decltype); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); write_args(proxy, args, iface->name, 1, TRUE); print_proxy( ")\n"); write_client_call_routine( proxy, iface, func, "Object", proc_offset ); return; } print_proxy( "static void __finally_%s_%s_Proxy( struct __proxy_frame *__frame )\n", iface->name, get_name(func) ); print_proxy( "{\n"); indent++; if (has_full_pointer) write_full_pointer_free(proxy, indent, func); print_proxy( "NdrProxyFreeBuffer( __frame->This, &__frame->_StubMsg );\n" ); indent--; print_proxy( "}\n"); print_proxy( "\n");
- write_type_decl_left(proxy, retval->type); + write_decltype_decl_left(proxy, (decl_type_t*)&retval->decltype); print_proxy( " %s %s_%s_Proxy(\n", callconv, iface->name, get_name(func)); write_args(proxy, args, iface->name, 1, TRUE); print_proxy( ")\n"); print_proxy( "{\n"); indent ++; print_proxy( "struct __proxy_frame __f, * const __frame = &__f;\n" ); /* local variables */ if (has_ret) { print_proxy( "%s", "" ); - write_type_decl(proxy, retval->type, retval->name); + write_decltype_decl(proxy, &retval->decltype, retval->name); fprintf( proxy, ";\n" ); } print_proxy( "RPC_MESSAGE _RpcMessage;\n" ); if (has_ret) { - if (decl_indirect(retval->type)) + if (decl_indirect(retval->decltype.type)) print_proxy("void *_p_%s = &%s;\n", retval->name, retval->name); } print_proxy( "\n");
print_proxy( "RpcExceptionInit( __proxy_filter, __finally_%s_%s_Proxy );\n", iface->name, get_name(func) ); print_proxy( "__frame->This = This;\n" );
if (has_full_pointer) write_full_pointer_init(proxy, indent, func, FALSE);
/* FIXME: trace */ - clear_output_vars( type_get_function_args(func->type) ); + clear_output_vars( type_get_function_args(func->decltype.type) );
print_proxy( "RpcTryExcept\n" ); print_proxy( "{\n" ); indent++; print_proxy( "NdrProxyInitialize(This, &_RpcMessage, &__frame->_StubMsg, &Object_StubDesc, %d);\n", idx); write_pointer_checks( proxy, indent, func );
print_proxy( "RpcTryFinally\n" ); @@ -274,19 +274,19 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx, print_proxy("NdrConvert( &__frame->_StubMsg, &__MIDL_ProcFormatString.Format[%u]);\n", proc_offset ); indent--; fprintf(proxy, "\n");
write_remoting_arguments(proxy, indent, func, "", PASS_OUT, PHASE_UNMARSHAL);
if (has_ret) { - if (decl_indirect(retval->type)) + if (decl_indirect(retval->decltype.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->decltype.type) || is_array(retval->decltype.type)) print_proxy("%s = 0;\n", retval->name); write_remoting_arguments(proxy, indent, func, "", PASS_RETURN, PHASE_UNMARSHAL); }
indent--; print_proxy( "}\n"); print_proxy( "RpcFinally\n" ); print_proxy( "{\n" ); @@ -296,17 +296,17 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx, print_proxy( "}\n"); print_proxy( "RpcEndFinally\n" ); indent--; print_proxy( "}\n" ); print_proxy( "RpcExcept(__frame->_StubMsg.dwStubPhase != PROXY_SENDRECEIVE)\n" ); print_proxy( "{\n" ); if (has_ret) { indent++; - proxy_free_variables( type_get_function_args(func->type), "" ); + proxy_free_variables( type_get_function_args(func->decltype.type), "" ); print_proxy( "_RetVal = NdrProxyErrorHandler(RpcExceptionCode());\n" ); indent--; } print_proxy( "}\n" ); print_proxy( "RpcEndExcept\n" );
if (has_ret) { print_proxy( "return _RetVal;\n" ); @@ -315,17 +315,17 @@ static void gen_proxy(type_t *iface, const var_t *func, int idx, print_proxy( "}\n"); print_proxy( "\n"); }
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->decltype.type)); int has_full_pointer = is_full_pointer_function(func);
if (is_interpreted_func( iface, func )) return;
indent = 0; print_proxy( "struct __frame_%s_%s_Stub\n{\n", iface->name, get_name(func)); indent++; print_proxy( "__DECL_EXCEPTION_FRAME\n" ); @@ -384,38 +384,38 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas,
print_proxy("*_pdwStubPhase = STUB_CALL_SERVER;\n"); fprintf(proxy, "\n"); print_proxy( "%s", has_ret ? "__frame->_RetVal = " : "" ); if (cas) fprintf(proxy, "%s_%s_Stub", iface->name, cas); else fprintf(proxy, "__frame->_This->lpVtbl->%s", get_name(func)); fprintf(proxy, "(__frame->_This");
- if (type_get_function_args(func->type)) + if (type_get_function_args(func->decltype.type)) { - LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), const var_t, entry ) - fprintf(proxy, ", %s__frame->%s", is_array(arg->type) && !type_array_is_decl_as_ptr(arg->type) ? "*" :"" , arg->name); + LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->decltype.type), const var_t, entry ) + fprintf(proxy, ", %s__frame->%s", is_array(arg->decltype.type) && !type_array_is_decl_as_ptr(arg->decltype.type) ? "*" :"" , arg->name); } fprintf(proxy, ");\n"); fprintf(proxy, "\n"); print_proxy("*_pdwStubPhase = STUB_MARSHAL;\n"); fprintf(proxy, "\n");
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->decltype.type))) write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_BUFFERSIZE);
print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &__frame->_StubMsg);\n");
write_remoting_arguments(proxy, indent, func, "__frame->", PASS_OUT, PHASE_MARSHAL); fprintf(proxy, "\n");
/* marshall the return value */ - if (!is_void(type_function_get_rettype(func->type))) + if (!is_void(type_function_get_rettype(func->decltype.type))) write_remoting_arguments(proxy, indent, func, "__frame->", PASS_RETURN, PHASE_MARSHAL);
indent--; print_proxy("}\n"); print_proxy("RpcFinally\n"); print_proxy("{\n"); indent++; print_proxy( "__finally_%s_%s_Stub( __frame );\n", iface->name, get_name(func) ); @@ -427,26 +427,26 @@ static void gen_stub(type_t *iface, const var_t *func, const char *cas, indent--;
print_proxy("}\n"); print_proxy("\n"); }
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->decltype.type )); const var_t *arg, *callas = is_callas( func->attrs ); - const var_list_t *args = type_get_function_args( func->type ); + const var_list_t *args = type_get_function_args( func->decltype.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->decltype.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 ); indent++; if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) { fprintf( proxy, ",\n%*spParamStruct->%s", 4 * indent, "", arg->name ); } @@ -608,24 +608,24 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset) fprintf(proxy, "/*****************************************************************************\n"); fprintf(proxy, " * %s interface\n", iface->name); fprintf(proxy, " */\n"); first_func = 0; } if (!is_local(func->attrs)) { const var_t *cas = is_callas(func->attrs); const char *cname = cas ? cas->name : NULL; - int idx = func->type->details.function->idx; + int idx = func->decltype.type->details.function->idx; if (cname) { const statement_t *stmt2; STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) { const var_t *m = stmt2->u.var; if (!strcmp(m->name, cname)) { - idx = m->type->details.function->idx; + idx = m->decltype.type->details.function->idx; break; } } } func->procstring_offset = *proc_offset; gen_proxy(iface, func, idx, *proc_offset); gen_stub(iface, func, cname, *proc_offset); if (cas && is_interpreted_func( iface, func )) diff --git a/tools/widl/server.c b/tools/widl/server.c index 59c17d661f..d50fa2b596 100644 --- a/tools/widl/server.c +++ b/tools/widl/server.c @@ -50,17 +50,18 @@ static void print_server(const char *format, ...) }
static void write_function_stub(const type_t *iface, const var_t *func, unsigned int proc_offset) { const var_t *var; unsigned char explicit_fc, implicit_fc; int has_full_pointer = is_full_pointer_function(func); const var_t *handle_var = get_func_handle_var( iface, func, &explicit_fc, &implicit_fc ); - type_t *ret_type = type_function_get_rettype(func->type); + decl_type_t *ret_decltype = type_function_get_retdecltype(func->decltype.type); + type_t *ret_type = ret_decltype->type;
if (is_interpreted_func( iface, func )) return;
print_server("struct __frame_%s_%s\n{\n", iface->name, get_name(func)); indent++; print_server("__DECL_EXCEPTION_FRAME\n"); print_server("MIDL_STUB_MESSAGE _StubMsg;\n");
@@ -116,17 +117,17 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned indent++; print_server("RpcTryExcept\n"); print_server("{\n"); indent++;
if (has_full_pointer) write_full_pointer_init(server, indent, func, TRUE);
- if (type_get_function_args(func->type)) + if (type_get_function_args(func->decltype.type)) { print_server("if ((_pRpcMessage->DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; print_server("NdrConvert(&__frame->_StubMsg, (PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset); indent--; fprintf(server, "\n");
@@ -154,48 +155,48 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned /* Assign 'out' arguments */ assign_stub_out_args(server, indent, func, "__frame->");
/* Call the real server function */ if (is_context_handle(ret_type)) { print_server("__frame->_RetVal = NDRSContextUnmarshall((char*)0, _pRpcMessage->DataRepresentation);\n"); print_server("*(("); - write_type_decl(server, ret_type, NULL); + write_decltype_decl(server, ret_decltype, 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_get_function_args(func->decltype.type)) { int first_arg = 1;
fprintf(server, "(\n"); indent++; - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.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->decltype.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->decltype.type, ATTR_CONTEXTHANDLE) ? "*" : ""; print_server("("); - write_type_decl_left(server, var->type); + write_decltype_decl_left(server, (decl_type_t*)&var->decltype); 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->decltype.type) && !type_array_is_decl_as_ptr(var->decltype.type) ? "*" : "", var->name); } } fprintf(server, ");\n"); indent--; } else { fprintf(server, "();\n"); diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index e5fb20c55f..785cc13b07 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -80,24 +80,24 @@ static const unsigned short IsReturn = 0x0020; static const unsigned short IsBasetype = 0x0040; static const unsigned short IsByValue = 0x0080; static const unsigned short IsSimpleRef = 0x0100; /* static const unsigned short IsDontCallFreeInst = 0x0200; */ /* static const unsigned short SaveForAsyncFinish = 0x0400; */
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, decl_type_t *decltype, 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, decl_type_t *decltype, const char *name, unsigned int *tfsoff); +static int write_embedded_types(FILE *file, const attr_list_t *attrs, decl_type_t *decltype, 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, + decl_type_t *decltype, 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, unsigned int *alignment ); static unsigned int get_function_buffer_size( const var_t *func, enum pass pass );
static const char *string_of_type(unsigned char type) { @@ -192,17 +192,17 @@ static const char *string_of_type(unsigned char type) static void *get_aliaschain_attrp(const type_t *type, enum attr_type attr) { const type_t *t = type; for (;;) { 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; } }
unsigned char get_basic_fc(const type_t *type) { int sign = type_basic_get_sign(type); switch (type_basic_get_type(type)) @@ -262,17 +262,17 @@ unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int t int pointer_type;
assert(is_ptr(type) || is_array(type));
pointer_type = get_attrv(attrs, ATTR_POINTERTYPE); 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) return pointer_type; }
if (toplevel_param) return FC_RP; @@ -298,35 +298,44 @@ static unsigned char get_enum_fc(const type_t *type) { assert(type_get_type(type) == TYPE_ENUM); if (is_aliaschain_attr(type, ATTR_V1ENUM)) return FC_ENUM32; else return FC_ENUM16; }
-static type_t *get_user_type(const type_t *t, const char **pname) +static decl_type_t *get_user_decltype(const type_t *t, const char **pname) { for (;;) { - type_t *ut = get_attrp(t->attrs, ATTR_WIREMARSHAL); - if (ut) + decl_type_t *udt = get_attrdt(t->attrs, ATTR_WIREMARSHAL); + if (udt) { if (pname) *pname = t->name; - return ut; + return udt; }
if (type_is_alias(t)) - t = type_alias_get_aliasee(t); + t = type_alias_get_aliasee_type(t); else return NULL; } }
+static type_t *get_user_type(const type_t *t, const char **pname) +{ + decl_type_t *decltype = get_user_decltype(t, pname); + if (decltype != NULL) { + return decltype->type; + } + return NULL; +} + static int is_user_type(const type_t *t) { return get_user_type(t, NULL) != NULL; }
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags) { if (is_user_type(type)) @@ -346,20 +355,20 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att return TGT_RANGE; return TGT_BASIC; case TYPE_ENUM: if (!(flags & TDT_IGNORE_RANGES) && (is_attr(attrs, ATTR_RANGE) || is_aliaschain_attr(type, ATTR_RANGE))) 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; case TYPE_STRUCT: return TGT_STRUCT; case TYPE_ENCAPSULATED_UNION: case TYPE_UNION: return TGT_UNION; @@ -374,68 +383,67 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att case TYPE_BITFIELD: break; } return TGT_INVALID; }
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->decltype.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->decltype.type )) return 0; /* fall through */ case TGT_POINTER: - return (get_pointer_fc(v->type, v->attrs, TRUE) == FC_RP); + return (get_pointer_fc(v->decltype.type, v->attrs, TRUE) == FC_RP); case TGT_CTXT_HANDLE_POINTER: return TRUE; default: return 0; } - }
static int get_padding(const var_list_t *fields) { unsigned short offset = 0; unsigned int salign = 1; const var_t *f;
if (!fields) return 0;
LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry) { - type_t *ft = f->type; + type_t *ft = f->decltype.type; unsigned int align = 0; unsigned int size = type_memsize_and_alignment(ft, &align); align = clamp_align(align); if (align > salign) salign = align; offset = ROUND_SIZE(offset, align); offset += size; }
return ROUNDING(offset, salign); }
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->decltype.type, var->attrs, TDT_ALL_TYPES )) { case TGT_BASIC: case TGT_ENUM: case TGT_RANGE: case TGT_STRUCT: case TGT_UNION: case TGT_USER_TYPE: - stack_size = type_memsize( var->type ); + stack_size = type_memsize( var->decltype.type ); by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */ break; default: by_val = 0; break; } if (!by_val) stack_size = pointer_size; if (by_value) *by_value = by_val; @@ -490,45 +498,45 @@ unsigned char get_struct_fc(const type_t *type)
fields = type_struct_get_fields(type);
if (get_padding(fields)) return FC_BOGUS_STRUCT;
if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry ) { - type_t *t = field->type; + type_t *t = field->decltype.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->decltype.type)) { if (is_conformant_array(t)) has_conformance = 1; has_variance = 1; continue; }
- if (is_array(type_array_get_element(field->type))) + if (is_array(type_array_get_element_type(field->decltype.type))) return FC_BOGUS_STRUCT;
- if (type_array_has_conformance(field->type)) + if (type_array_has_conformance(field->decltype.type)) { has_conformance = 1; if (list_next(fields, &field->entry)) error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", field->name); } 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); }
switch (typegen_type) { case TGT_USER_TYPE: case TGT_IFACE_POINTER: return FC_BOGUS_STRUCT; @@ -620,17 +628,17 @@ unsigned char get_struct_fc(const type_t *type) }
static unsigned char get_array_fc(const type_t *type) { unsigned char fc; 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) { unsigned int size = type_memsize(elem_type); if (size * type_array_get_dim(type) > 0xffffuL) fc = FC_LGFARRAY; else @@ -709,36 +717,36 @@ static int type_has_pointers(const type_t *type) { switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS)) { case TGT_USER_TYPE: return FALSE; 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->decltype.type)) return TRUE; } break; } case TGT_UNION: { var_list_t *fields; const var_t *field; 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->decltype.type && type_has_pointers(field->decltype.type)) return TRUE; } break; } case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: case TGT_STRING: case TGT_IFACE_POINTER: @@ -763,36 +771,36 @@ 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 FALSE; case TGT_ARRAY: 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->decltype.type, field->attrs, FALSE)) return TRUE; } break; } case TGT_UNION: { var_list_t *fields; const var_t *field; 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->decltype.type && type_has_full_pointer(field->decltype.type, field->attrs, FALSE)) return TRUE; } break; } case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: case TGT_STRING: case TGT_IFACE_POINTER: @@ -852,17 +860,17 @@ static int is_embedded_complex(const type_t *type) } }
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); return NULL; }
#define WRITE_FCTYPE(file, fctype, typestring_offset) \ do { \ @@ -902,26 +910,26 @@ static void write_var_init(FILE *file, int indent, const type_t *t, const char * print_file(file, indent, "%s_p_%s = &%s%s;\n", local_var_prefix, n, local_var_prefix, n); } else if (is_ptr(t) || is_array(t)) print_file(file, indent, "%s%s = 0;\n", local_var_prefix, n); }
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->decltype.type);
- if (!is_void(var->type)) - write_var_init(file, indent, var->type, var->name, local_var_prefix); + if (!is_void(var->decltype.type)) + write_var_init(file, indent, var->decltype.type, var->name, local_var_prefix);
- if (!type_get_function_args(func->type)) + if (!type_get_function_args(func->decltype.type)) return;
- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) - write_var_init(file, indent, var->type, var->name, local_var_prefix); + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.type), const var_t, entry ) + write_var_init(file, indent, var->decltype.type, var->name, local_var_prefix);
fprintf(file, "\n"); }
static void write_formatdesc(FILE *f, int indent, const char *str) { print_file(f, indent, "typedef struct _MIDL_%s_FORMAT_STRING\n", str); print_file(f, indent, "{\n"); @@ -975,75 +983,75 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned *flags = 0; *stack_size = get_stack_size( var, &is_byval ); *typestring_offset = var->typestring_offset;
if (is_in) *flags |= IsIn; 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->decltype.type )) + buffer_size = get_required_buffer_size_type( var->decltype.type, NULL, var->attrs, TRUE, &alignment );
- switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES )) + switch (typegen_detect_type( var->decltype.type, var->attrs, TDT_ALL_TYPES )) { case TGT_BASIC: *flags |= IsBasetype; - fc = get_basic_fc_signed( var->type ); + fc = get_basic_fc_signed( var->decltype.type ); if (fc == FC_BIND_PRIMITIVE) { buffer_size = 4; /* actually 0 but avoids setting MustSize */ fc = FC_LONG; } break; case TGT_ENUM: *flags |= IsBasetype; - fc = get_enum_fc( var->type ); + fc = get_enum_fc( var->decltype.type ); break; case TGT_RANGE: *flags |= IsByValue; break; case TGT_STRUCT: case TGT_UNION: case TGT_USER_TYPE: *flags |= MustFree | (is_byval ? IsByValue : IsSimpleRef); break; case TGT_IFACE_POINTER: *flags |= MustFree; 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->decltype.type) && var->decltype.type->details.array.ptr_tfsoff && + get_pointer_fc( var->decltype.type, var->attrs, !is_return ) == FC_RP) { - *typestring_offset = var->type->typestring_offset; + *typestring_offset = var->decltype.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->decltype.type ) && get_pointer_fc( var->decltype.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->decltype.type )) *typestring_offset += 4; else *typestring_offset += 2; *flags |= IsSimpleRef; } break; case TGT_CTXT_HANDLE_POINTER: *flags |= IsSimpleRef; *typestring_offset += 4; /* fall through */ case TGT_CTXT_HANDLE: buffer_size = 20; break; case TGT_POINTER: - if (get_pointer_fc( var->type, var->attrs, !is_return ) == FC_RP) + if (get_pointer_fc( var->decltype.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->decltype.type );
if (!is_string_type( var->attrs, ref )) buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment );
switch (typegen_detect_type( ref, NULL, TDT_ALL_TYPES )) { case TGT_BASIC: *flags |= IsSimpleRef | IsBasetype; @@ -1115,33 +1123,33 @@ static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned if (server_size < 8) *flags |= server_size << 13; } return fc; }
static unsigned char get_func_oi2_flags( const var_t *func ) { const var_t *var; - var_list_t *args = type_get_function_args( func->type ); - var_t *retval = type_function_get_retval( func->type ); + var_list_t *args = type_get_function_args( func->decltype.type ); + var_t *retval = type_function_get_retval( func->decltype.type ); unsigned char oi2_flags = 0x40; /* HasExtensions */ unsigned short flags; unsigned int stack_size, typestring_offset;
if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry ) { get_parameter_fc( var, 0, &flags, &stack_size, &typestring_offset ); if (flags & MustSize) { if (flags & IsIn) oi2_flags |= 0x02; /* ClientMustSize */ if (flags & IsOut) oi2_flags |= 0x01; /* ServerMustSize */ } }
- if (!is_void( retval->type )) + if (!is_void( retval->decltype.type )) { oi2_flags |= 0x04; /* HasRet */ get_parameter_fc( retval, 1, &flags, &stack_size, &typestring_offset ); if (flags & MustSize) oi2_flags |= 0x01; /* ServerMustSize */ } return oi2_flags; }
@@ -1185,50 +1193,50 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons { unsigned int size;
int is_in = is_attr(var->attrs, ATTR_IN); int is_out = is_attr(var->attrs, ATTR_OUT);
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->decltype.type) == TYPE_BASIC || + type_get_type(var->decltype.type) == TYPE_ENUM) { unsigned char fc;
if (is_return) print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n"); else print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
- if (type_get_type(var->type) == TYPE_ENUM) + if (type_get_type(var->decltype.type) == TYPE_ENUM) { - fc = get_enum_fc(var->type); + fc = get_enum_fc(var->decltype.type); } else { - fc = get_basic_fc_signed(var->type); + fc = get_basic_fc_signed(var->decltype.type);
if (fc == FC_BIND_PRIMITIVE) fc = FC_IGNORE; }
print_file(file, indent, "0x%02x, /* %s */\n", fc, string_of_type(fc)); size = 2; /* includes param type prefix */ } else { 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->decltype.type) && + type_array_is_decl_as_ptr(var->decltype.type) && + var->decltype.type->details.array.ptr_tfsoff) + offset = var->decltype.type->typestring_offset;
if (is_return) print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n"); else if (is_in && is_out) print_file(file, indent, "0x50, /* FC_IN_OUT_PARAM */\n"); else if (is_out) print_file(file, indent, "0x51, /* FC_OUT_PARAM */\n"); else @@ -1241,18 +1249,18 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent, cons } return size; }
int is_interpreted_func( const type_t *iface, const var_t *func ) { const char *str; const var_t *var; - const var_list_t *args = type_get_function_args( func->type ); - const type_t *ret_type = type_function_get_rettype( func->type ); + const var_list_t *args = type_get_function_args( func->decltype.type ); + const type_t *ret_type = type_function_get_rettype( func->decltype.type );
if (type_get_type( ret_type ) == TYPE_BASIC) { switch (type_basic_get_type( ret_type )) { case TYPE_BASIC_INT64: case TYPE_BASIC_HYPER: /* return value must fit in a long_ptr */ @@ -1264,20 +1272,20 @@ int is_interpreted_func( const type_t *iface, const var_t *func ) return 0; default: break; } } 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->decltype.type )) { case TYPE_BASIC: - switch (type_basic_get_type( var->type )) + switch (type_basic_get_type( var->decltype.type )) { /* floating point arguments are not supported in Oi mode */ case TYPE_BASIC_FLOAT: return 0; case TYPE_BASIC_DOUBLE: return 0; default: break; } break; /* unions passed by value are not supported in Oi mode */ @@ -1292,17 +1300,17 @@ int is_interpreted_func( const type_t *iface, const var_t *func ) return (get_stub_mode() != MODE_Os); }
static void write_proc_func_header( FILE *file, int indent, const type_t *iface, const var_t *func, unsigned int *offset, unsigned short num_proc ) { var_t *var; - var_list_t *args = type_get_function_args( func->type ); + var_list_t *args = type_get_function_args( func->decltype.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 ); unsigned char oi_flags = Oi_HAS_RPCFLAGS | Oi_USE_NEW_INIT_ROUTINES; unsigned int rpc_flags = get_rpc_flags( func->attrs ); unsigned int nb_args = 0; unsigned int stack_size = 0; unsigned short param_num = 0; @@ -1323,17 +1331,17 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface, { handle_stack_offset = stack_size; handle_param_num = param_num; } stack_size += get_stack_size( var, NULL ); param_num++; nb_args++; } - if (!is_void( type_function_get_rettype( func->type ))) + if (!is_void( type_function_get_rettype( func->decltype.type ))) { stack_size += pointer_size; nb_args++; }
print_file( file, 0, "/* %u (procedure %s::%s) */\n", *offset, iface->name, func->name ); print_file( file, indent, "0x%02x,\t/* %s */\n", implicit_fc, implicit_fc ? string_of_type(implicit_fc) : "explicit handle" ); @@ -1351,32 +1359,32 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface, handle_flags = 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 ); *offset += 4; break; case FC_BIND_GENERIC: - handle_flags = type_memsize( handle_var->type ); + handle_flags = type_memsize( handle_var->decltype.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->decltype.type ) ); print_file( file, indent, "0x%x,\t/* FC_PAD */\n", FC_PAD); *offset += 6; break; case FC_BIND_CONTEXT: - handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->type, 0 ); + handle_flags = get_contexthandle_flags( iface, handle_var->attrs, handle_var->decltype.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->decltype.type ) ); print_file( file, indent, "0x%02x,\t/* param %hu */\n", handle_param_num, handle_param_num ); *offset += 6; break; } }
if (get_stub_mode() == MODE_Oif) { @@ -1402,19 +1410,19 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface, *offset += 14; if (pointer_size == 8) { unsigned short pos = 0, fpu_mask = 0;
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->decltype.type ) == TYPE_BASIC) { - switch (type_basic_get_type( var->type )) + switch (type_basic_get_type( var->decltype.type )) { case TYPE_BASIC_FLOAT: fpu_mask |= 1 << pos; break; case TYPE_BASIC_DOUBLE: fpu_mask |= 2 << pos; break; default: break; } } pos += 2; if (pos >= 16) break; @@ -1427,36 +1435,36 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
static void write_procformatstring_func( FILE *file, int indent, const type_t *iface, const var_t *func, unsigned int *offset, unsigned short num_proc ) { 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->decltype.type );
if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc );
/* emit argument data */ - if (type_get_function_args(func->type)) + if (type_get_function_args(func->decltype.type)) { const var_t *var; - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.type), const var_t, entry ) { print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name ); if (is_new_style) *offset += write_new_procformatstring_type(file, indent, var, FALSE, &stack_offset); else *offset += write_old_procformatstring_type(file, indent, var, FALSE, is_interpreted); } }
/* emit return value data */ - if (is_void(retval->type)) + if (is_void(retval->decltype.type)) { if (!is_new_style) { print_file(file, 0, "/* %u (void) */\n", *offset); print_file(file, indent, "0x5b,\t/* FC_END */\n"); print_file(file, indent, "0x5c,\t/* FC_PAD */\n"); *offset += 2; } @@ -1593,17 +1601,17 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
return 4; }
if (!cont_type) /* top-level conformance */ { conftype = FC_TOP_LEVEL_CONFORMANCE; conftype_string = "parameter"; - cont_type = current_func->type; + cont_type = current_func->decltype.type; name = current_func->name; iface = current_iface; } else { name = cont_type->name; if (is_ptr(type) || (is_array(type) && type_array_is_decl_as_ptr(type))) { @@ -1664,33 +1672,33 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type, var_list_t *args = type_get_function_args( cont_type );
if (is_object( iface )) offset += pointer_size; if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry ) { if (var->name && !strcmp(var->name, subexpr->u.sval)) { expr_loc.v = var; - correlation_variable = var->type; + correlation_variable = var->decltype.type; break; } offset += get_stack_size( var, NULL ); } } else { var_list_t *fields = type_struct_get_fields( 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->decltype.type, &offset ); if (var->name && !strcmp(var->name, subexpr->u.sval)) { expr_loc.v = var; - correlation_variable = var->type; + correlation_variable = var->decltype.type; break; } offset += size; } }
if (!correlation_variable) error("write_conf_or_var_desc: couldn't find variable %s in %s\n", subexpr->u.sval, name); @@ -1819,17 +1827,17 @@ static unsigned int fields_memsize(const var_list_t *fields, unsigned int *align unsigned int size = 0; unsigned int max_align; const var_t *v;
if (!fields) return 0; 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->decltype.type, &falign); if (*align < falign) *align = falign; falign = clamp_align(falign); size = ROUND_SIZE(size, falign); size += fsize; }
max_align = clamp_align(*align); size = ROUND_SIZE(size, max_align); @@ -1841,19 +1849,19 @@ static unsigned int union_memsize(const var_list_t *fields, unsigned int *pmaxa) { unsigned int size, maxs = 0; unsigned int align = *pmaxa; const var_t *v;
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->decltype.type) { - size = type_memsize_and_alignment(v->type, &align); + size = type_memsize_and_alignment(v->decltype.type, &align); if (maxs < size) maxs = size; if (*pmaxa < align) *pmaxa = align; } }
return maxs; }
@@ -1931,22 +1939,22 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align) size = pointer_size; if (size > *align) *align = size; break; case TYPE_ARRAY: if (!type_array_is_decl_as_ptr(t)) { 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 */ { assert( pointer_size ); size = pointer_size; if (size > *align) *align = size; } break; @@ -2016,42 +2024,42 @@ static unsigned int type_buffer_alignment(const type_t *t) default: error("type_buffer_alignment: Unknown enum type\n"); } break; case TYPE_STRUCT: 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->decltype.type) continue; + align = type_buffer_alignment( var->decltype.type ); if (max < align) max = align; } break; case TYPE_ENCAPSULATED_UNION: 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->decltype.type) continue; + align = type_buffer_alignment( var->decltype.type ); if (max < align) max = align; } break; case TYPE_UNION: 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->decltype.type) continue; + align = type_buffer_alignment( var->decltype.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; case TYPE_INTERFACE: case TYPE_ALIAS: case TYPE_VOID: case TYPE_COCLASS: case TYPE_MODULE: @@ -2064,22 +2072,22 @@ static unsigned int type_buffer_alignment(const type_t *t) assert(0); } return max; }
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->decltype.type), func->attrs, TRUE)) return TRUE; - if (!type_get_function_args(func->type)) + if (!type_get_function_args(func->decltype.type)) return FALSE; - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) - if (type_has_full_pointer( var->type, var->attrs, TRUE )) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.type), const var_t, entry ) + if (type_has_full_pointer( var->decltype.type, var->attrs, TRUE )) return TRUE; return FALSE; }
void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_server) { print_file(file, indent, "__frame->_StubMsg.FullPtrXlatTables = NdrFullPointerXlatInit(0,%s);\n", is_server ? "XLAT_SERVER" : "XLAT_CLIENT"); @@ -2114,17 +2122,17 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs { if (out_attr && !in_attr && pointer_type == FC_RP) flags |= FC_ALLOCED_ON_STACK; } else if (get_stub_mode() == MODE_Oif) { 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: flags |= FC_ALLOCED_ON_STACK; break; case TGT_IFACE_POINTER: @@ -2134,17 +2142,17 @@ static unsigned int write_nonsimple_pointer(FILE *file, const attr_list_t *attrs default: break; } } }
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; }
print_file(file, 2, "0x%x, 0x%x,\t\t/* %s", pointer_type, flags, string_of_type(pointer_type)); @@ -2175,17 +2183,17 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs,
/* for historical reasons, write_simple_pointer also handled string types, * but no longer does. catch bad uses of the function with this check */ if (is_string_type(attrs, type)) error("write_simple_pointer: can't handle type %s which is a string type\n", type->name);
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 fc = get_basic_fc(ref);
if (!is_interpreted_func(current_iface, current_func)) { if (out_attr && !in_attr && pointer_fc == FC_RP) @@ -2200,32 +2208,33 @@ static unsigned int write_simple_pointer(FILE *file, const attr_list_t *attrs, print_file(file, 2, "0x%02x, 0x%x,\t/* %s %s[simple_pointer] */\n", pointer_fc, flags, string_of_type(pointer_fc), flags & FC_ALLOCED_ON_STACK ? "[allocated_on_stack] " : ""); print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc)); print_file(file, 2, "0x5c,\t/* FC_PAD */\n"); return 4; }
-static void print_start_tfs_comment(FILE *file, type_t *t, unsigned int tfsoff) +static void print_start_tfs_comment(FILE *file, decl_type_t *dt, unsigned int tfsoff) { print_file(file, 0, "/* %u (", tfsoff); - write_type_decl(file, t, NULL); + write_decltype_decl(file, dt, 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, + decl_type_t *decltype, 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 = decltype->type; + type_t *ref = type_pointer_get_ref_type(type);
- print_start_tfs_comment(file, type, offset); + print_start_tfs_comment(file, decltype, offset); update_tfsoff(type, offset, file);
switch (typegen_detect_type(ref, attrs, TDT_ALL_TYPES)) { case TGT_BASIC: case TGT_ENUM: *typestring_offset += write_simple_pointer(file, attrs, type, context); break; @@ -2258,21 +2267,23 @@ static int user_type_has_variable_size(const type_t *t) return TRUE; } } /* Note: Since this only applies to user types, we can't have a conformant array here, and strings should get filed under pointer in this case. */ return FALSE; }
-static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) +static unsigned int write_user_tfs(FILE *file, decl_type_t *decltype, unsigned int *tfsoff) { unsigned int start, absoff, flags; const char *name = NULL; - type_t *utype = get_user_type(type, &name); + type_t *type = decltype->type; + decl_type_t *udecltype = get_user_decltype(type, &name); + type_t *utype = udecltype ? udecltype->type : NULL; unsigned int usize = type_memsize(utype); unsigned int ualign = type_buffer_alignment(utype); unsigned int size = type_memsize(type); unsigned short funoff = user_type_offset(name); short reloff;
if (processed(type)) return type->typestring_offset;
@@ -2286,38 +2297,40 @@ static unsigned int write_user_tfs(FILE *file, type_t *type, unsigned int *tfsof unsigned char fc;
if (type_get_type(utype) == TYPE_ENUM) fc = get_enum_fc(utype); else fc = get_basic_fc(utype);
absoff = *tfsoff; - print_start_tfs_comment(file, utype, absoff); + print_start_tfs_comment(file, udecltype, 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; } else { if (!processed(utype)) - write_embedded_types(file, NULL, utype, utype->name, TRUE, tfsoff); + { + write_embedded_types(file, NULL, udecltype, utype->name, TRUE, tfsoff); + } absoff = utype->typestring_offset; }
if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype, NULL, FALSE) == FC_RP) flags = 0x40; else if (type_get_type(utype) == TYPE_POINTER && get_pointer_fc(utype, NULL, FALSE) == FC_UP) flags = 0x80; else flags = 0;
start = *tfsoff; update_tfsoff(type, start, file); - print_start_tfs_comment(file, type, start); + print_start_tfs_comment(file, decltype, 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); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Function offset= %hu */\n", funoff, funoff); print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)size, size); print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)usize, usize); *tfsoff += 8; reloff = absoff - *tfsoff; @@ -2364,41 +2377,42 @@ static void write_member_type(FILE *file, const type_t *cont, } else if (!write_base_type(file, type, tfsoff)) error("Unsupported member type %d\n", type_get_type(type)); }
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); + decl_type_t *elem = type_array_get_element(type); + type_t *elemtype = elem->type;
- if (!is_embedded_complex(elem) && is_ptr(elem)) + if (!is_embedded_complex(elemtype) && is_ptr(elemtype)) { - type_t *ref = type_pointer_get_ref(elem); + type_t *ref = type_pointer_get_ref_type(elemtype);
if (processed(ref)) { - write_nonsimple_pointer(file, NULL, elem, TYPE_CONTEXT_CONTAINER, + write_nonsimple_pointer(file, NULL, elemtype, TYPE_CONTEXT_CONTAINER, ref->typestring_offset, tfsoff); return; } - if (cont_is_complex && is_string_type(attrs, elem)) + if (cont_is_complex && is_string_type(attrs, elemtype)) { write_string_tfs(file, NULL, elem, TYPE_CONTEXT_CONTAINER, NULL, tfsoff); return; } - if (!is_string_type(NULL, elem) && + if (!is_string_type(NULL, elemtype) && (type_get_type(ref) == TYPE_BASIC || type_get_type(ref) == TYPE_ENUM)) { - *tfsoff += write_simple_pointer(file, NULL, elem, TYPE_CONTEXT_CONTAINER); + *tfsoff += write_simple_pointer(file, NULL, elemtype, TYPE_CONTEXT_CONTAINER); return; } } - write_member_type(file, type, cont_is_complex, NULL, elem, NULL, tfsoff); + write_member_type(file, type, cont_is_complex, NULL, elemtype, NULL, tfsoff); }
static void write_end(FILE *file, unsigned int *tfsoff) { if (*tfsoff % 2 == 0) { print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD); *tfsoff += 1; @@ -2410,17 +2424,17 @@ static void write_end(FILE *file, unsigned int *tfsoff) static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff) { unsigned int offset = 0; var_list_t *fs = type_struct_get_fields(type); var_t *f;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry) { - type_t *ft = f->type; + type_t *ft = f->decltype.type; unsigned int size = field_memsize( ft, &offset ); if (type_get_type(ft) == TYPE_UNION && is_attr(f->attrs, ATTR_SWITCHIS)) { short reloff; unsigned int absoff = ft->typestring_offset; if (is_attr(ft->attrs, ATTR_SWITCHTYPE)) absoff += 8; /* we already have a corr descr, skip it */ reloff = absoff - (*tfsoff + 6); @@ -2433,23 +2447,24 @@ static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff) (unsigned short)reloff, reloff, absoff); *tfsoff += 8; } offset += size; } }
static int write_pointer_description_offsets( - FILE *file, const attr_list_t *attrs, type_t *type, + FILE *file, const attr_list_t *attrs, decl_type_t *decltype, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset) { + type_t *type = decltype->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) { unsigned int memsize;
/* pointer instance * @@ -2464,20 +2479,20 @@ static int write_pointer_description_offsets( /* increment these separately as in the case of conformant (varying) * structures these start at different values */ *offset_in_buffer += memsize; } *typestring_offset += 4;
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, decltype, TYPE_CONTEXT_CONTAINER, NULL, typestring_offset); else if (processed(ref)) write_nonsimple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER, ref->typestring_offset, typestring_offset); else if (type_get_type(ref) == TYPE_BASIC || type_get_type(ref) == TYPE_ENUM) *typestring_offset += write_simple_pointer(file, attrs, type, TYPE_CONTEXT_CONTAINER); else error("write_pointer_description_offsets: type format string unknown\n"); } @@ -2505,23 +2520,23 @@ static int write_pointer_description_offsets( /* otherwise search for interesting fields to parse */ const var_t *v; LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry ) { if (offset_in_memory && offset_in_buffer) { unsigned int padding; unsigned int align = 0; - type_memsize_and_alignment(v->type, &align); + type_memsize_and_alignment(v->decltype.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, (decl_type_t*)&v->decltype, offset_in_memory, offset_in_buffer, typestring_offset); } } else { if (offset_in_memory && offset_in_buffer) { unsigned int memsize = type_memsize(type); @@ -2531,49 +2546,50 @@ static int write_pointer_description_offsets( *offset_in_buffer += memsize; } }
return written; }
static int write_no_repeat_pointer_descriptions( - FILE *file, const attr_list_t *attrs, type_t *type, + FILE *file, const attr_list_t *attrs, decl_type_t *decltype, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset) { + type_t *type = decltype->type; int written = 0;
if (is_ptr(type) || (is_conformant_array(type) && type_array_is_decl_as_ptr(type))) { print_file(file, 2, "0x%02x, /* FC_NO_REPEAT */\n", FC_NO_REPEAT); 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, decltype, offset_in_memory, offset_in_buffer, typestring_offset); }
if (is_non_complex_struct(type)) { const var_t *v; LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry ) { if (offset_in_memory && offset_in_buffer) { unsigned int padding; unsigned int align = 0; - type_memsize_and_alignment(v->type, &align); + type_memsize_and_alignment(v->decltype.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, (decl_type_t*)&v->decltype, offset_in_memory, offset_in_buffer, typestring_offset); } } else { unsigned int memsize = type_memsize(type); *offset_in_memory += memsize; /* increment these separately as in the case of conformant (varying) @@ -2582,67 +2598,68 @@ static int write_no_repeat_pointer_descriptions( }
return written; }
/* 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, decl_type_t *decltype, unsigned int *offset_in_memory, unsigned int *offset_in_buffer, unsigned int *typestring_offset) { + type_t *type = decltype->type; int pointer_count = 0;
if (type_get_type(type) == TYPE_ARRAY && !type_array_has_conformance(type) && !type_array_has_variance(type)) { unsigned int temp = 0; /* unfortunately, this needs to be done in two passes to avoid * writing out redundant FC_FIXED_REPEAT descriptions */ pointer_count = write_pointer_description_offsets( NULL, attrs, type_array_get_element(type), NULL, NULL, &temp); if (pointer_count > 0) { unsigned int increment_size; 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); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Iterations = %d */\n", (unsigned short)type_array_get_dim(type), type_array_get_dim(type)); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Increment = %d */\n", (unsigned short)increment_size, increment_size); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset to array = %d */\n", (unsigned short)*offset_in_memory, *offset_in_memory); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Number of pointers = %d */\n", (unsigned short)pointer_count, pointer_count); *typestring_offset += 10;
pointer_count = write_pointer_description_offsets( - file, attrs, type, &offset_of_array_pointer_mem, + file, attrs, decltype, &offset_of_array_pointer_mem, &offset_of_array_pointer_buf, typestring_offset); } } else if (type_get_type(type) == TYPE_STRUCT) { const var_t *v; LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry ) { if (offset_in_memory && offset_in_buffer) { unsigned int padding; unsigned int align = 0; - type_memsize_and_alignment(v->type, &align); + type_memsize_and_alignment(v->decltype.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, (decl_type_t*)&v->decltype, offset_in_memory, offset_in_buffer, typestring_offset); } } else { if (offset_in_memory && offset_in_buffer) { unsigned int memsize; @@ -2673,17 +2690,17 @@ static int write_conformant_array_pointer_descriptions( pointer_count = write_pointer_description_offsets( NULL, attrs, type_array_get_element(type), NULL, NULL, &temp); if (pointer_count > 0) { unsigned int increment_size; 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);
print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", FC_VARIABLE_REPEAT); print_file(file, 2, "0x%02x, /* FC_FIXED_OFFSET */\n", FC_FIXED_OFFSET); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Increment = %d */\n", (unsigned short)increment_size, increment_size); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset to array = %d */\n", (unsigned short)offset_in_memory, offset_in_memory); @@ -2715,17 +2732,17 @@ static int write_varying_array_pointer_descriptions( /* unfortunately, this needs to be done in two passes to avoid * writing out redundant FC_VARIABLE_REPEAT descriptions */ pointer_count = write_pointer_description_offsets( NULL, attrs, type_array_get_element(type), NULL, NULL, &temp); if (pointer_count > 0) { 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);
print_file(file, 2, "0x%02x, /* FC_VARIABLE_REPEAT */\n", FC_VARIABLE_REPEAT); print_file(file, 2, "0x%02x, /* FC_VARIABLE_OFFSET */\n", FC_VARIABLE_OFFSET); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Increment = %d */\n", (unsigned short)increment_size, increment_size); print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset to array = %d */\n", (unsigned short)*offset_in_memory, *offset_in_memory); @@ -2741,30 +2758,30 @@ static int write_varying_array_pointer_descriptions( { const var_t *v; LIST_FOR_EACH_ENTRY( v, type_struct_get_fields(type), const var_t, entry ) { if (offset_in_memory && offset_in_buffer) { unsigned int align = 0, padding;
- if (is_array(v->type) && type_array_has_variance(v->type)) + if (is_array(v->decltype.type) && type_array_has_variance(v->decltype.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->decltype.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->decltype.type, offset_in_memory, offset_in_buffer, typestring_offset); } } else { if (offset_in_memory && offset_in_buffer) { unsigned int memsize = type_memsize(type); @@ -2773,99 +2790,103 @@ static int write_varying_array_pointer_descriptions( * structures these start at different values */ *offset_in_buffer += memsize; } }
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, decl_type_t *decltype, unsigned int *typestring_offset) { + type_t *type = decltype->type; unsigned int offset_in_buffer; unsigned int offset_in_memory;
/* pass 1: search for single instance of a pointer (i.e. don't descend * into arrays) */ if (!is_array(type)) { offset_in_memory = 0; offset_in_buffer = 0; write_no_repeat_pointer_descriptions( - file, NULL, type, + file, NULL, decltype, &offset_in_memory, &offset_in_buffer, typestring_offset); }
/* pass 2: search for pointers in fixed arrays */ offset_in_memory = 0; offset_in_buffer = 0; write_fixed_array_pointer_descriptions( - file, NULL, type, + file, NULL, decltype, &offset_in_memory, &offset_in_buffer, typestring_offset);
/* pass 3: search for pointers in conformant only arrays (but don't descend * into conformant varying or varying arrays) */ if (is_conformant_array(type) && (type_array_is_decl_as_ptr(type) || !current_structure)) write_conformant_array_pointer_descriptions( file, attrs, type, 0, typestring_offset); 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)->decltype.type; write_conformant_array_pointer_descriptions( file, NULL, carray, type_memsize(type), typestring_offset); }
/* pass 4: search for pointers in varying arrays */ offset_in_memory = 0; offset_in_buffer = 0; write_varying_array_pointer_descriptions( file, NULL, type, &offset_in_memory, &offset_in_buffer, typestring_offset); }
static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, - type_t *type, enum type_context context, + decl_type_t *decltype, enum type_context context, const char *name, unsigned int *typestring_offset) { + type_t *type = decltype->type; unsigned int start_offset; unsigned char rtype; type_t *elem_type; int is_processed = processed(type);
start_offset = *typestring_offset;
if (is_declptr(type)) { unsigned char flag = is_conformant_array(type) ? 0 : FC_SIMPLE_POINTER; 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, decltype, *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]" : ""); *typestring_offset += 2; if (!flag) { print_file(file, 2, "NdrFcShort(0x2),\n"); *typestring_offset += 2; } is_processed = FALSE; }
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, decltype, name, typestring_offset);
if (type_get_type(elem_type) != TYPE_BASIC) { error("write_string_tfs: Unimplemented for non-basic type %s\n", name); return start_offset; }
rtype = get_basic_fc(elem_type); @@ -2929,44 +2950,45 @@ static unsigned int write_string_tfs(FILE *file, const attr_list_t *attrs, print_file(file, 2, "0x%x,\t/* FC_PAD */\n", FC_PAD); *typestring_offset += 2;
update_tfsoff(type, start_offset, file); return start_offset; } }
-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, decl_type_t *decltype, const char *name, unsigned int *typestring_offset) { + type_t *type = decltype->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, decltype, 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;
align = 0; if (fc != FC_BOGUS_ARRAY) { if (fc == FC_LGFARRAY || fc == FC_LGVARRAY) @@ -2982,17 +3004,17 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t
if (is_conformant_array(type)) *typestring_offset += write_conf_or_var_desc(file, current_structure, baseoff, type, size_is);
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) { print_file(file, 2, "NdrFcLong(0x%x),\t/* %u */\n", dim, dim); *typestring_offset += 4; } else @@ -3005,23 +3027,23 @@ static unsigned int write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *typestring_offset += 2; }
if (length_is) *typestring_offset += 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, decltype, typestring_offset); print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END); *typestring_offset += 1; }
write_array_element_type(file, is_string_type(attrs, type) ? attrs : NULL, type, FALSE, typestring_offset); write_end(file, typestring_offset); } else @@ -3048,17 +3070,17 @@ static const var_t *find_array_or_string_in_struct(const type_t *type) const var_list_t *fields = type_struct_get_fields(type); const var_t *last_field; const type_t *ft;
if (!fields || list_empty(fields)) return NULL;
last_field = LIST_ENTRY( list_tail(fields), const var_t, entry ); - ft = last_field->type; + ft = last_field->decltype.type;
if (is_conformant_array(ft) && !type_array_is_decl_as_ptr(ft)) return last_field;
if (type_get_type(ft) == TYPE_STRUCT) return find_array_or_string_in_struct(ft); else return NULL; @@ -3071,17 +3093,17 @@ static void write_struct_members(FILE *file, const type_t *type, const var_t *field; unsigned short offset = 0; unsigned int salign = 1; int padding; var_list_t *fields = type_struct_get_fields(type);
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) { - type_t *ft = field->type; + type_t *ft = field->decltype.type; unsigned int align = 0; unsigned int size = type_memsize_and_alignment(ft, &align); align = clamp_align(align); if (salign < align) salign = align;
if (!is_conformant_array(ft) || type_array_is_decl_as_ptr(ft)) { if ((align - 1) & offset) @@ -3100,17 +3122,17 @@ static void write_struct_members(FILE *file, const type_t *type, break; default: error("write_struct_members: cannot align type %d\n", type_get_type(ft)); } print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc)); 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->decltype.type, corroff, typestring_offset); offset += size; } }
padding = ROUNDING(offset, salign); if (padding) { @@ -3118,19 +3140,20 @@ static void write_struct_members(FILE *file, const type_t *type, FC_STRUCTPAD1 + padding - 1, padding); *typestring_offset += 1; }
write_end(file, typestring_offset); }
-static unsigned int write_struct_tfs(FILE *file, type_t *type, +static unsigned int write_struct_tfs(FILE *file, decl_type_t *decltype, const char *name, unsigned int *tfsoff) { + type_t *type = decltype->type; const type_t *save_current_structure = current_structure; unsigned int total_size; const var_t *array; unsigned int start_offset; unsigned int align; unsigned int corroff; var_t *f; unsigned char fc = get_struct_fc(type); @@ -3143,41 +3166,41 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type,
total_size = type_memsize(type); align = type_buffer_alignment(type); if (total_size > USHRT_MAX) error("structure size for %s exceeds %d bytes by %d bytes\n", 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->decltype, f->name, FALSE, tfsoff);
array = find_array_or_string_in_struct(type); - if (array && !processed(array->type)) + if (array && !processed(array->decltype.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->decltype.type)) + write_string_tfs(file, array->attrs, (decl_type_t*)&array->decltype, TYPE_CONTEXT_CONTAINER, array->name, tfsoff); else - write_array_tfs(file, array->attrs, array->type, array->name, tfsoff); + write_array_tfs(file, array->attrs, (decl_type_t*)&array->decltype, array->name, tfsoff); }
corroff = *tfsoff; write_descriptors(file, type, tfsoff);
start_offset = *tfsoff; update_tfsoff(type, start_offset, file); - print_start_tfs_comment(file, type, start_offset); + print_start_tfs_comment(file, decltype, 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); *tfsoff += 4;
if (array) { - unsigned int absoff = array->type->typestring_offset; + unsigned int absoff = array->decltype.type->typestring_offset; short reloff = absoff - *tfsoff; print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n", reloff, reloff, absoff); *tfsoff += 2; } else if (fc == FC_BOGUS_STRUCT) { print_file(file, 2, "NdrFcShort(0x0),\n"); @@ -3198,40 +3221,41 @@ static unsigned int write_struct_tfs(FILE *file, type_t *type, } else if ((fc == FC_PSTRUCT) || (fc == FC_CPSTRUCT) || (fc == FC_CVSTRUCT && type_has_pointers(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, decltype, tfsoff); print_file(file, 2, "0x%x,\t/* FC_END */\n", FC_END); *tfsoff += 1; }
write_struct_members(file, type, fc == FC_BOGUS_STRUCT, &corroff, tfsoff);
if (fc == FC_BOGUS_STRUCT) { const var_t *f;
type->ptrdesc = *tfsoff; if (fields) LIST_FOR_EACH_ENTRY(f, fields, const var_t, entry) { - type_t *ft = f->type; + decl_type_t *fdt = (decl_type_t*)&f->decltype; + type_t *ft = fdt->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, fdt, 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, fdt, + type_pointer_get_ref_type(ft)->typestring_offset, TYPE_CONTEXT_CONTAINER, tfsoff); break; case TGT_ARRAY: if (type_array_is_decl_as_ptr(ft)) { unsigned int offset;
print_file(file, 0, "/* %d */\n", *tfsoff); @@ -3283,18 +3307,19 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff) else error("write_branch_type: type unimplemented %d\n", type_get_type(t)); }
*tfsoff += 2; }
static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs, - type_t *type, unsigned int *tfsoff) + decl_type_t *decltype, unsigned int *tfsoff) { + type_t* type = decltype->type; unsigned int start_offset; unsigned int size; var_list_t *fields; unsigned int nbranch = 0; type_t *deftype = NULL; short nodeftype = 0xffff; unsigned int dummy; var_t *f; @@ -3309,27 +3334,28 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
size = union_memsize(fields, &dummy);
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry) { 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->decltype.type) + write_embedded_types(file, f->attrs, &f->decltype, 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, decltype, 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->decltype.type; unsigned int align = 0; unsigned char fc;
if (type_get_type(st) == TYPE_BASIC) { fc = get_basic_fc(st); switch (fc) { @@ -3351,18 +3377,18 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs, else if (type_get_type(st) == TYPE_ENUM) fc = get_enum_fc(st); else error("union switch type must be an integer, char, or enum\n");
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->decltype.type) + type_memsize_and_alignment(f->decltype.type, &align); }
print_file(file, 2, "0x%x,\t/* FC_ENCAPSULATED_UNION */\n", FC_ENCAPSULATED_UNION); print_file(file, 2, "0x%x,\t/* Switch type= %s */\n", (align << 4) | fc, string_of_type(fc)); *tfsoff += 2; } else if (is_attr(type->attrs, ATTR_SWITCHTYPE)) @@ -3407,17 +3433,17 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs, }
print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)size, size); print_file(file, 2, "NdrFcShort(0x%hx),\t/* %d */\n", (unsigned short)nbranch, nbranch); *tfsoff += 4;
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry) { - type_t *ft = f->type; + type_t *ft = f->decltype.type; expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE); int deflt = is_attr(f->attrs, ATTR_DEFAULT); expr_t *c;
if (cases == NULL && !deflt) error("union field %s with neither case nor default attribute\n", f->name);
if (cases) LIST_FOR_EACH_ENTRY(c, cases, expr_t, entry) @@ -3448,38 +3474,39 @@ static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs, { print_file(file, 2, "NdrFcShort(0x%hx),\n", nodeftype); *tfsoff += 2; }
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, decl_type_t *decltype, unsigned int *typeformat_offset) { unsigned int i; + type_t *type = decltype->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, decltype, start_offset); update_tfsoff(type, start_offset, file);
if (iid) { print_file(file, 2, "0x2f, /* FC_IP */\n"); print_file(file, 2, "0x5c, /* FC_PAD */\n"); *typeformat_offset += write_conf_or_var_desc(file, current_structure, 0, type, iid) + 2; } 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) error("%s: interface %s missing UUID\n", __FUNCTION__, base->name);
print_file(file, 2, "0x2f,\t/* FC_IP */\n"); print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n"); print_file(file, 2, "NdrFcLong(0x%08x),\n", uuid->Data1); @@ -3493,24 +3520,25 @@ static unsigned int write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *t
*typeformat_offset += 18; } return start_offset; }
static unsigned int write_contexthandle_tfs(FILE *file, const attr_list_t *attrs, - type_t *type, + decl_type_t *decltype, enum type_context context, unsigned int *typeformat_offset) { + type_t *type = decltype->type; unsigned int start_offset = *typeformat_offset; 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, decltype, start_offset);
if (flags & 0x80) /* via ptr */ { 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) ); print_file(file, 2, "NdrFcShort(0x2),\t /* Offset= 2 (%u) */\n", *typeformat_offset); @@ -3568,40 +3596,41 @@ static unsigned int write_range_tfs(FILE *file, const attr_list_t *attrs, print_file(file, 2, "NdrFcLong(0x%x),\t/* %u */\n", range_max->cval, range_max->cval); update_tfsoff( type, start_offset, file ); *typeformat_offset += 10;
return start_offset; }
static unsigned int write_type_tfs(FILE *file, int indent, - const attr_list_t *attrs, type_t *type, + const attr_list_t *attrs, decl_type_t *decltype, const char *name, enum type_context context, unsigned int *typeformat_offset) { unsigned int offset; + type_t *type = decltype->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, typeformat_offset); + return write_contexthandle_tfs(file, attrs, decltype, context, typeformat_offset); case TGT_USER_TYPE: - return write_user_tfs(file, type, typeformat_offset); + return write_user_tfs(file, decltype, typeformat_offset); case TGT_STRING: - return write_string_tfs(file, attrs, type, context, name, typeformat_offset); + return write_string_tfs(file, attrs, decltype, context, name, typeformat_offset); case TGT_ARRAY: { unsigned int off; /* conformant and pointer arrays are handled specially */ 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, decltype, 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); @@ -3618,72 +3647,73 @@ 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; } return off; } case TGT_STRUCT: - return write_struct_tfs(file, type, name, typeformat_offset); + return write_struct_tfs(file, decltype, name, typeformat_offset); case TGT_UNION: - return write_union_tfs(file, attrs, type, typeformat_offset); + return write_union_tfs(file, attrs, decltype, typeformat_offset); case TGT_ENUM: case TGT_BASIC: /* nothing to do */ return 0; case TGT_RANGE: { expr_list_t *range_list = get_attrp(attrs, ATTR_RANGE); if (!range_list) range_list = get_aliaschain_attrp(type, ATTR_RANGE); 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, decltype, typeformat_offset); case TGT_POINTER: { enum type_context ref_context; - type_t *ref = type_pointer_get_ref(type); + decl_type_t *ref = type_pointer_get_ref(type); + type_t *reftype = ref->type;
if (context == TYPE_CONTEXT_TOPLEVELPARAM) ref_context = TYPE_CONTEXT_PARAM; else if (context == TYPE_CONTEXT_CONTAINER_NO_POINTERS) ref_context = TYPE_CONTEXT_CONTAINER; else ref_context = context;
- if (is_string_type(attrs, ref)) + if (is_string_type(attrs, reftype)) { if (context != TYPE_CONTEXT_CONTAINER_NO_POINTERS) - write_pointer_tfs(file, attrs, type, *typeformat_offset + 4, context, typeformat_offset); + write_pointer_tfs(file, attrs, decltype, *typeformat_offset + 4, context, typeformat_offset);
offset = write_type_tfs(file, indent, 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, 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, decltype, offset, context, typeformat_offset); } case TGT_INVALID: break; } error("invalid type %s for var %s\n", type->name, name); 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, decl_type_t *decltype, 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, 2, attrs, decltype, 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) { const statement_list_t *stmts = type_iface_get_stmts(iface); const statement_t *stmt; var_t *var;
@@ -3691,44 +3721,44 @@ static void process_tfs_iface(type_t *iface, FILE *file, int indent, unsigned in if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry ) { switch(stmt->type) { 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->decltype.stgclass != STG_NONE + || type_get_type_detect_alias(stmt->u.var->decltype.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, var->attrs, var->type, func->name, + var = type_function_get_retval(func->decltype.type); + if (!is_void(var->decltype.type)) + var->typestring_offset = write_type_tfs( file, 2, var->attrs, &var->decltype, 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_get_function_args(func->decltype.type)) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.type), var_t, entry ) + var->typestring_offset = write_type_tfs( file, 2, var->attrs, &var->decltype, var->name, TYPE_CONTEXT_TOPLEVELPARAM, offset ); break;
} case STMT_TYPEDEF: { - const type_list_t *type_entry; - for (type_entry = stmt->u.type_list; type_entry; type_entry = type_entry->next) + const typedef_list_t *typedef_entry; + for (typedef_entry = stmt->u.typedef_list; typedef_entry; typedef_entry = typedef_entry->next) { - 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, + if (is_attr(typedef_entry->var->decltype.type->attrs, ATTR_ENCODE) + || is_attr(typedef_entry->var->decltype.type->attrs, ATTR_DECODE)) + typedef_entry->var->decltype.type->typestring_offset = write_type_tfs( file, 2, + typedef_entry->var->decltype.type->attrs, &typedef_entry->var->decltype, typedef_entry->var->decltype.type->name, TYPE_CONTEXT_CONTAINER, offset); } break; } default: break; } } @@ -3840,17 +3870,17 @@ static unsigned int get_required_buffer_size_type( if (!type_struct_get_fields(type)) return 0; return fields_memsize(type_struct_get_fields(type), alignment); } break;
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) { size += 4 + align; align = 4; } *alignment = align; @@ -3860,17 +3890,17 @@ static unsigned int get_required_buffer_size_type( case TGT_ARRAY: if (get_pointer_fc(type, attrs, toplevel_param) == FC_RP) { switch (get_array_fc(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); } } break;
default: break; } @@ -3891,41 +3921,41 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali pass == PASS_RETURN) { if (is_ptrchain_attr(var, ATTR_CONTEXTHANDLE)) { *alignment = 4; 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->decltype.type)) + return get_required_buffer_size_type(var->decltype.type, var->name, var->attrs, TRUE, alignment); } return 0; }
static unsigned int get_function_buffer_size( const var_t *func, enum pass pass ) { const var_t *var; unsigned int total_size = 0, alignment;
- if (type_get_function_args(func->type)) + if (type_get_function_args(func->decltype.type)) { - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.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->decltype.type))) { var_t v = *func; - v.type = type_function_get_rettype(func->type); + v.decltype.type = type_function_get_rettype(func->decltype.type); total_size += get_required_buffer_size(&v, &alignment, PASS_RETURN); total_size += alignment; } return total_size; }
static void print_phase_function(FILE *file, int indent, const char *type, const char *local_var_prefix, enum remoting_phase phase, @@ -3951,32 +3981,33 @@ static void print_phase_function(FILE *file, int indent, const char *type, return; }
print_file(file, indent, "Ndr%s%s(\n", type, function); indent++; 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->decltype.type)) ? "&" : "", local_var_prefix, - (phase == PHASE_UNMARSHAL && decl_indirect(var->type)) ? "_p_" : "", + (phase == PHASE_UNMARSHAL && decl_indirect(var->decltype.type)) ? "_p_" : "", var->name); print_file(file, indent, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]%s\n", type_offset, (phase == PHASE_UNMARSHAL) ? "," : ");"); if (phase == PHASE_UNMARSHAL) print_file(file, indent, "0);\n"); indent--; }
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; + decl_type_t *decltype = (decl_type_t*)&var->decltype; + type_t *type = decltype->type; unsigned int alignment = 0;
/* no work to do for other phases, buffer sizing is done elsewhere */ if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) return;
if (type_get_type(type) == TYPE_ENUM || (type_get_type(type) == TYPE_BASIC && @@ -3997,18 +4028,19 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, print_file(file, indent+1, "&__frame->_StubMsg,\n"); print_file(file, indent+1, "(unsigned char *)&%s%s,\n", local_var_prefix, var->name); print_file(file, indent+1, "0x%02x /* %s */);\n", fc, string_of_type(fc)); } else { - const type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : type; - switch (get_basic_fc(ref)) + const decl_type_t *ref = is_ptr(type) ? type_pointer_get_ref(type) : decltype; + const type_t *reftype = ref->type; + switch (get_basic_fc(reftype)) { case FC_BYTE: case FC_CHAR: case FC_SMALL: case FC_USMALL: alignment = 1; break;
@@ -4035,72 +4067,72 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix,
case FC_IGNORE: case FC_BIND_PRIMITIVE: /* no marshalling needed */ return;
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(reftype)); }
if (phase == PHASE_MARSHAL && alignment > 1) print_file(file, indent, "MIDL_memset(__frame->_StubMsg.Buffer, 0, (0x%x - (ULONG_PTR)__frame->_StubMsg.Buffer) & 0x%x);\n", alignment, alignment - 1); print_file(file, indent, "__frame->_StubMsg.Buffer = (unsigned char *)(((ULONG_PTR)__frame->_StubMsg.Buffer + %u) & ~0x%x);\n", alignment - 1, alignment - 1);
if (phase == PHASE_MARSHAL) { print_file(file, indent, "*("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + write_decltype_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : decltype, NULL); if (is_ptr(type)) fprintf(file, " *)__frame->_StubMsg.Buffer = *"); else fprintf(file, " *)__frame->_StubMsg.Buffer = "); fprintf(file, "%s%s", local_var_prefix, varname); fprintf(file, ";\n"); } 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_decltype_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : decltype, NULL); fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n"); print_file(file, indent, "{\n"); print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); print_file(file, indent, "}\n"); print_file(file, indent, "%s%s%s", (pass == PASS_IN || pass == PASS_RETURN) ? "" : "*", local_var_prefix, varname); if (pass == PASS_IN && is_ptr(type)) fprintf(file, " = ("); else fprintf(file, " = *("); - write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); + write_decltype_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : decltype, 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_decltype_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : decltype, NULL); fprintf(file, ");\n"); } }
/* returns whether the MaxCount, Offset or ActualCount members need to be * filled in for the specified phase */ static inline int is_conformance_needed_for_phase(enum remoting_phase phase) { return (phase != PHASE_UNMARSHAL); }
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) { if (!x) x = type_array_get_conformance(t); else error("%s: multidimensional conformant" " arrays not supported at the top level\n", @@ -4108,17 +4140,17 @@ expr_t *get_size_is_expr(const type_t *t, const char *name) }
return x; }
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->decltype.type; /* get fundamental type for the argument */ for (;;) { switch (typegen_detect_type(type, var->attrs, TDT_IGNORE_STRINGS|TDT_IGNORE_RANGES)) { case TGT_ARRAY: if (is_conformance_needed_for_phase(phase)) { @@ -4160,17 +4192,17 @@ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local { print_file( file, indent, "__frame->_StubMsg.MaxCount = (ULONG_PTR) " ); write_expr( file, iid, 1, 1, NULL, NULL, local_var_prefix ); fprintf( file, ";\n\n" ); } 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: case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: case TGT_STRING: case TGT_BASIC: case TGT_ENUM: @@ -4182,17 +4214,17 @@ void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char *local } }
static void write_remoting_arg(FILE *file, int indent, const var_t *func, const char *local_var_prefix, enum pass pass, enum remoting_phase phase, const var_t *var) { int in_attr, out_attr, pointer_type; const char *type_str = NULL; - const type_t *type = var->type; + const type_t *type = var->decltype.type; unsigned int alignment, start_offset = type->typestring_offset;
if (is_ptr(type) || is_array(type)) pointer_type = get_pointer_fc(type, var->attrs, pass != PASS_RETURN); else pointer_type = 0;
in_attr = is_attr(var->attrs, ATTR_IN); @@ -4235,17 +4267,17 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const var->name); print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0"); } else { 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->decltype.type)); print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset); } } else if (phase == PHASE_UNMARSHAL) { if (pass == PASS_OUT || pass == PASS_RETURN) { if (!in_attr) @@ -4379,19 +4411,19 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const const expr_t *range_max; expr_list_t *range_list = get_attrp(var->attrs, ATTR_RANGE); if (!range_list) range_list = get_aliaschain_attrp(type, ATTR_RANGE); range_min = LIST_ENTRY(list_head(range_list), const expr_t, entry); 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_decltype_decl(file, (decl_type_t*)&var->decltype, NULL); fprintf(file, ")0x%x) || (%s%s > (", range_min->cval, local_var_prefix, var->name); - write_type_decl(file, var->type, NULL); + write_decltype_decl(file, (decl_type_t*)&var->decltype, 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"); print_file(file, indent, "}\n"); } break; case TGT_STRUCT: switch (get_struct_fc(type)) @@ -4427,17 +4459,17 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const union_type = "EncapsulatedUnion";
print_phase_function(file, indent, union_type, local_var_prefix, phase, var, start_offset); break; } 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: print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name); break; case TGT_ENUM: /* base types have known sizes, so don't need a sizing pass * and don't have any memory to free and so don't need a @@ -4548,24 +4580,24 @@ void write_remoting_arguments(FILE *file, int indent, const var_t *func, const c { unsigned int size = get_function_buffer_size( func, pass ); print_file(file, indent, "__frame->_StubMsg.BufferLength = %u;\n", size); }
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->decltype.type) ); } else { const var_t *var; - if (!type_get_function_args(func->type)) + if (!type_get_function_args(func->decltype.type)) return; - LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.type), const var_t, entry ) write_remoting_arg( file, indent, func, local_var_prefix, pass, phase, var ); } }
unsigned int get_size_procformatstring_func(const type_t *iface, const var_t *func) { unsigned int offset = 0; @@ -4596,167 +4628,167 @@ unsigned int get_size_typeformatstring(const statement_list_t *stmts, type_pred_ set_all_tfswrite(FALSE); return process_tfs(NULL, stmts, pred); }
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->decltype.type);
/* declare return value */ - if (!is_void(var->type)) + if (!is_void(var->decltype.type)) { - if (is_context_handle(var->type)) + if (is_context_handle(var->decltype.type)) print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name); else { print_file(file, indent, "%s", ""); - write_type_decl(file, var->type, var->name); + write_decltype_decl(file, (decl_type_t*)&var->decltype, var->name); fprintf(file, ";\n"); } }
- if (!type_get_function_args(func->type)) + if (!type_get_function_args(func->decltype.type)) return;
- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.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->decltype.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->decltype.type)) { - type_t *type_to_print; + decl_type_t *decltype_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->decltype.type) == TYPE_ARRAY && + !type_array_is_decl_as_ptr(var->decltype.type)) + decltype_to_print = (decl_type_t*)&var->decltype; else - type_to_print = type_pointer_get_ref(var->type); + decltype_to_print = type_pointer_get_ref(var->decltype.type); sprintf(name, "_W%u", i++); - write_type_decl(file, type_to_print, name); + write_decltype_decl(file, decltype_to_print, name); fprintf(file, ";\n"); }
print_file(file, indent, "%s", ""); - write_type_decl_left(file, var->type); + write_decltype_decl_left(file, (decl_type_t*)&var->decltype); fprintf(file, " "); - if (type_get_type(var->type) == TYPE_ARRAY && - !type_array_is_decl_as_ptr(var->type)) { + if (type_get_type(var->decltype.type) == TYPE_ARRAY && + !type_array_is_decl_as_ptr(var->decltype.type)) { fprintf(file, "(*%s)", var->name); } else fprintf(file, "%s", var->name); - write_type_right(file, var->type, FALSE); + write_type_right(file, var->decltype.type, FALSE); fprintf(file, ";\n");
- if (decl_indirect(var->type)) + if (decl_indirect(var->decltype.type)) print_file(file, indent, "void *_p_%s;\n", var->name); } } }
void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char *local_var_prefix ) { int in_attr, out_attr; int i = 0, sep = 0; const var_t *var; - type_t *ref; + type_t *reftype;
- if (!type_get_function_args(func->type)) + if (!type_get_function_args(func->decltype.type)) return;
- LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->type), const var_t, entry ) + LIST_FOR_EACH_ENTRY( var, type_get_function_args(func->decltype.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 (!in_attr) { 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->decltype.type, var->attrs, TDT_IGNORE_STRINGS)) { case TGT_CTXT_HANDLE_POINTER: fprintf(file, " = NdrContextHandleInitialize(\n"); print_file(file, indent + 1, "&__frame->_StubMsg,\n"); print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", var->typestring_offset); break; case TGT_ARRAY: - if (type_array_has_conformance(var->type)) + if (type_array_has_conformance(var->decltype.type)) { unsigned int size; type_t *type;
fprintf(file, " = NdrAllocate(&__frame->_StubMsg, "); - for (type = var->type; + for (type = var->decltype.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); fprintf(file, " * "); } size = type_memsize(type); 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->decltype.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); fprintf(file, " * "); } size = type_memsize(type); fprintf(file, "%u);\n", size); } else fprintf(file, " = &%s_W%u;\n", local_var_prefix, i++); break; case TGT_POINTER: fprintf(file, " = &%s_W%u;\n", local_var_prefix, i); - ref = type_pointer_get_ref(var->type); - switch (typegen_detect_type(ref, var->attrs, TDT_IGNORE_STRINGS)) + reftype = type_pointer_get_ref_type(var->decltype.type); + switch (typegen_detect_type(reftype, var->attrs, TDT_IGNORE_STRINGS)) { case TGT_BASIC: case TGT_ENUM: case TGT_POINTER: case TGT_RANGE: case TGT_IFACE_POINTER: print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i); break; case TGT_USER_TYPE: print_file(file, indent, "memset(&%s_W%u, 0, sizeof(%s_W%u));\n", local_var_prefix, i, local_var_prefix, i); break; case TGT_ARRAY: - if (type_array_is_decl_as_ptr(ref)) + if (type_array_is_decl_as_ptr(reftype)) { print_file(file, indent, "%s_W%u = 0;\n", local_var_prefix, i); break; } - ref = type_array_get_element(ref); + reftype = type_array_get_element_type(reftype); /* fall through */ case TGT_STRUCT: case TGT_UNION: - if (type_has_pointers(ref)) + if (type_has_pointers(reftype)) print_file(file, indent, "memset(&%s_W%u, 0, sizeof(%s_W%u));\n", local_var_prefix, i, local_var_prefix, i); break; case TGT_CTXT_HANDLE: case TGT_CTXT_HANDLE_POINTER: case TGT_INVALID: case TGT_STRING: /* not initialised */ @@ -4782,60 +4814,60 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun var_t *retval = type_function_get_retval( func ); const var_list_t *args = type_get_function_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->decltype.type )) type_memsize_and_alignment( arg->decltype.type, &align );
needs_packing = (align > pointer_size);
if (needs_packing) print_file( file, 0, "#include <pshpack%u.h>\n", pointer_size ); print_file(file, 1, "struct _PARAM_STRUCT\n" ); print_file(file, 1, "{\n" ); if (is_object( iface )) print_file(file, 2, "%s *This;\n", iface->name );
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_decltype_left( file, (decl_type_t *)&arg->decltype, NAME_DEFAULT, TRUE ); + if (needs_space_after( arg->decltype.type )) fputc( ' ', file ); + if (is_array( arg->decltype.type ) && !type_array_is_decl_as_ptr( arg->decltype.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->decltype.type ) || is_ptr( arg->decltype.type )) align = pointer_size; + else type_memsize_and_alignment( arg->decltype.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->decltype.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_decltype_decl( file, (decl_type_t*)&retval->decltype, retval->name ); + if (is_array( retval->decltype.type ) || is_ptr( retval->decltype.type ) || + type_memsize( retval->decltype.type ) == pointer_size) fprintf( file, ";\n" ); else fprintf( file, " DECLSPEC_ALIGN(%u);\n", pointer_size ); } print_file(file, 1, "} %s;\n", var_decl ); if (needs_packing) print_file( file, 0, "#include <poppack.h>\n" ); print_file( file, 0, "\n" ); }
void write_pointer_checks( FILE *file, int indent, const var_t *func ) { - const var_list_t *args = type_get_function_args( func->type ); + const var_list_t *args = type_get_function_args( func->decltype.type ); const var_t *var;
if (!args) return;
LIST_FOR_EACH_ENTRY( var, args, const var_t, entry ) if (cant_be_null( var )) print_file( file, indent, "if (!%s) RpcRaiseException(RPC_X_NULL_REF_POINTER);\n", var->name ); } @@ -4858,20 +4890,21 @@ int write_expr_eval_routines(FILE *file, const char *iface) print_file(file, 0, "{\n"); if (type_get_type( eval->cont_type ) == TYPE_FUNCTION) { write_func_param_struct( file, eval->iface, eval->cont_type, "*pS = (struct _PARAM_STRUCT *)pStubMsg->StackTop", FALSE ); } else { + decl_type_t decltype; print_file(file, 1, "%s", ""); - write_type_left(file, (type_t *)eval->cont_type, NAME_DEFAULT, TRUE); + write_decltype_left(file, init_decltype(&decltype, (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_decltype_left(file, init_decltype(&decltype, (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 */ print_file(file, 1, "pStubMsg->MaxCount = (ULONG_PTR)"); write_expr(file, eval->expr, 1, 1, var_name_expr, eval->cont_type, ""); fprintf(file, ";\n"); print_file(file, 0, "}\n\n"); callback_offset++; @@ -4955,30 +4988,31 @@ void write_endpoints( FILE *f, const char *prefix, const str_list_t *list )
error: error("Invalid endpoint syntax '%s'\n", endpoint->str); }
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 ); + decl_type_t *retdecltype = type_function_get_retdecltype(func->decltype.type); + type_t *rettype = retdecltype->type; int has_ret = !is_void( rettype ); - const var_list_t *args = type_get_function_args( func->type ); + const var_list_t *args = type_get_function_args( func->decltype.type ); const var_t *arg; int len, needs_params = 0;
/* we need a param structure if we have more than one arg */ if (pointer_size == 4 && args) needs_params = is_object( iface ) || list_count( args ) > 1;
print_file( file, 0, "{\n"); 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->decltype.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 ) print_file( file, 1, "__params.%s = %s;\n", arg->name, arg->name ); } else if (has_ret) print_file( file, 1, "%s", "CLIENT_CALL_RETURN _RetVal;\n\n" );
len = fprintf( file, " %s%s( ", @@ -5005,17 +5039,17 @@ void write_client_call_routine( FILE *file, const type_t *iface, const var_t *fu arg = LIST_ENTRY( list_head(args), const var_t, entry ); fprintf( file, ",\n%*s&%s", len, "", arg->name ); } } fprintf( file, " );\n" ); if (has_ret) { print_file( file, 1, "return (" ); - write_type_decl_left(file, rettype); + write_decltype_decl_left(file, retdecltype); fprintf( file, ")%s;\n", pointer_size == 8 ? "_RetVal.Simple" : "*(LONG_PTR *)&_RetVal" ); } print_file( file, 0, "}\n\n"); }
void write_exceptions( FILE *file ) { fprintf( file, "#ifndef USE_COMPILER_EXCEPTIONS\n"); diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index 93f8f4de19..4f6b4fc38a 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -92,19 +92,19 @@ static unsigned short builtin_vt(const type_t *t) #endif if (kwp) { return kwp->vt; } if (is_string_type (t->attrs, 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)) { case TYPE_BASIC_CHAR: return VT_LPSTR; case TYPE_BASIC_WCHAR: return VT_LPWSTR; default: break; } @@ -193,17 +193,17 @@ unsigned short get_type_vt(type_t *t) break;
case TYPE_POINTER: return VT_PTR;
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; } else return VT_CARRAY;
case TYPE_INTERFACE: if(match(t->name, "IUnknown")) diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index b93806be98..b74448aa64 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -25,36 +25,24 @@ #include <string.h>
#include "widl.h" #include "utils.h" #include "parser.h" #include "typetree.h" #include "header.h"
-type_t *duptype(type_t *t, int dupname) -{ - type_t *d = alloc_type(); - - *d = *t; - if (dupname && t->name) - d->name = xstrdup(t->name); - - return d; -} - type_t *make_type(enum type_type type) { type_t *t = alloc_type(); t->name = NULL; t->namespace = NULL; 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; t->ignore = (parse_only != 0); t->defined = FALSE; t->written = FALSE; t->user_types_registered = FALSE; t->tfswrite = FALSE; @@ -132,27 +120,27 @@ type_t *type_new_function(var_list_t *args) { var_t *arg; type_t *t; unsigned int i = 0;
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->decltype.type && type_get_type(arg->decltype.type) == TYPE_VOID) { list_remove(&arg->entry); free(arg); free(args); args = NULL; } } if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry) { - if (arg->type && type_get_type(arg->type) == TYPE_VOID) + if (arg->decltype.type && type_get_type(arg->decltype.type) == TYPE_VOID) error_loc("argument '%s' has void type\n", arg->name); if (!arg->name) { if (i > 26 * 26) error_loc("too many unnamed arguments\n"); else { int unique; @@ -177,31 +165,36 @@ type_t *type_new_function(var_list_t *args) t->details.function->idx = -1; return t; }
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs) { type_t *t = make_type(TYPE_POINTER); t->details.pointer.def_fc = pointer_default; - t->details.pointer.ref = ref; + init_decltype(&t->details.pointer.ref, ref); t->attrs = attrs; return t; }
-type_t *type_new_alias(type_t *t, const char *name) +type_t* type_new_alias(const decl_type_t *decltype, const char *name, struct namespace *namespace) { - type_t *a = duptype(t, 0); + type_t *a = NULL; + + assert(decltype != NULL); + assert(name != NULL); + + a = alloc_type(); + *a = *decltype->type;
a->name = xstrdup(name); + a->namespace = namespace; a->attrs = NULL; - a->orig = t; + a->details.alias.aliasee = *decltype; 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); @@ -217,30 +210,33 @@ 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", 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, - unsigned int dim, expr_t *size_is, expr_t *length_is, - unsigned char ptr_default_fc) +type_t *type_new_array(const char *name, const decl_type_t *element, int declptr, + unsigned int dim, expr_t *size_is, expr_t *length_is, + unsigned char ptr_default_fc) { type_t *t = make_type(TYPE_ARRAY); if (name) t->name = xstrdup(name); t->details.array.declptr = declptr; t->details.array.length_is = length_is; - if (size_is) + if (size_is) { t->details.array.size_is = size_is; - else + } + 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; }
type_t *type_new_basic(enum type_basic_type basic_type) { type_t *t = make_type(TYPE_BASIC); t->details.basic.type = basic_type; @@ -268,24 +264,27 @@ type_t *type_new_void(void) static type_t *void_type = NULL; if (!void_type) void_type = make_type(TYPE_VOID); return void_type; }
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); + type_t *t; + + /* avoid creating duplicate typelib type entries */ + if (name && (t = find_type(name, namespace, tsENUM))) + return 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) + if (defined) { t->details.enumeration = xmalloc(sizeof(*t->details.enumeration)); t->details.enumeration->enums = enums; t->defined = TRUE; }
if (name) { @@ -294,72 +293,76 @@ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined 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; + if (name && (t = find_type(name, namespace, tsSTRUCT))) + return t;
t = make_type(TYPE_STRUCT); t->name = name; t->namespace = namespace;
- if (tag_type && tag_type->details.structure) - t->details.structure = tag_type->details.structure; - else if (defined) + if (defined) { t->details.structure = xmalloc(sizeof(*t->details.structure)); t->details.structure->fields = fields; t->defined = TRUE; } + if (name) { if (defined) reg_type(t, name, namespace, tsSTRUCT); 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); + type_t *t; + + /* avoid creating duplicate typelib type entries */ + if (name && (t = find_type(name, NULL, tsUNION))) + return 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) + + if (defined) { t->details.structure = xmalloc(sizeof(*t->details.structure)); t->details.structure->fields = fields; t->defined = TRUE; } + if (name) { if (defined) reg_type(t, name, NULL, tsUNION); else add_incomplete(t); } return t; }
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases) { 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->decltype.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 ); t->defined = TRUE; return t; }
static int is_valid_bitfield_type(const type_t *type) @@ -390,30 +393,30 @@ static int is_valid_bitfield_type(const type_t *type) return FALSE; } return FALSE; default: return FALSE; } }
-type_t *type_new_bitfield(type_t *field, const expr_t *bits) +type_t *type_new_bitfield(const decl_type_t *field, const expr_t *bits) { type_t *t;
- if (!is_valid_bitfield_type(field)) + if (!is_valid_bitfield_type(field->type)) error_loc("bit-field has invalid type\n");
if (bits->cval < 0) error_loc("negative width for bit-field\n");
/* FIXME: validate bits->cval <= memsize(field) * 8 */
t = make_type(TYPE_BITFIELD); - t->details.bitfield.field = field; + t->details.bitfield.field = *field; t->details.bitfield.bits = bits; return t; }
static int compute_method_indexes(type_t *iface) { int idx; statement_t *stmt; @@ -425,17 +428,17 @@ static int compute_method_indexes(type_t *iface) idx = compute_method_indexes(type_iface_get_inherit(iface)); else idx = 0;
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) { var_t *func = stmt->u.var; if (!is_callas(func->attrs)) - func->type->details.function->idx = idx++; + func->decltype.type->details.function->idx = idx++; }
return idx; }
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts) { iface->details.iface = xmalloc(sizeof(*iface->details.iface)); diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index fc134cd575..31669d6d59 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -26,46 +26,43 @@
enum name_type { NAME_DEFAULT, NAME_C };
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_alias(const decl_type_t *decltype, const char *name, struct namespace *namespace); 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_type_t *decltype, 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); type_t *type_new_int(enum type_basic_type basic_type, int sign); type_t *type_new_void(void); type_t *type_new_coclass(char *name); type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums); type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields); type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields); type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases); -type_t *type_new_bitfield(type_t *field_type, const expr_t *bits); +type_t *type_new_bitfield(const decl_type_t *decltype, const expr_t *bits); void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts); void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods); void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface); void type_module_define(type_t *module, statement_list_t *stmts); 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); - /* 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; }
static inline enum type_type type_get_type(const type_t *type) { return type_get_type_detect_alias(type_get_real_type(type)); } @@ -100,19 +97,24 @@ static inline var_list_t *type_function_get_args(const type_t *type)
static inline var_t *type_function_get_retval(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_FUNCTION); return type->details.function->retval; }
+static inline decl_type_t* type_function_get_retdecltype(const type_t *type) +{ + return &(type_function_get_retval(type)->decltype); +} + static inline type_t *type_function_get_rettype(const type_t *type) { - return type_function_get_retval(type)->type; + return type_function_get_retdecltype(type)->type; }
static inline var_list_t *type_enum_get_values(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_ENUM); return type->details.enumeration->enums; } @@ -137,17 +139,17 @@ static inline var_list_t *type_union_get_cases(const type_t *type)
type = type_get_real_type(type); type_type = type_get_type(type);
assert(type_type == TYPE_UNION || type_type == TYPE_ENCAPSULATED_UNION); 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->decltype.type->details.structure->fields; } else return type->details.structure->fields; }
static inline statement_list_t *type_iface_get_stmts(const type_t *type) { type = type_get_real_type(type); @@ -245,21 +247,28 @@ static inline expr_t *type_array_get_conformance(const type_t *type)
static inline expr_t *type_array_get_variance(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_ARRAY); return type->details.array.length_is; }
-static inline type_t *type_array_get_element(const type_t *type) +static inline decl_type_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 (decl_type_t*)&type->details.array.elem; +} + +static inline type_t *type_array_get_element_type(const type_t *type) +{ + decl_type_t *dt = type_array_get_element(type); + if (dt) return dt->type; + return NULL; }
static inline int type_array_is_decl_as_ptr(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_ARRAY); return type->details.array.declptr; } @@ -271,48 +280,62 @@ static inline unsigned char type_array_get_ptr_default_fc(const type_t *type) return type->details.array.ptr_def_fc; }
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 decl_type_t *type_alias_get_aliasee(const type_t *type) { assert(type_is_alias(type)); - return type->orig; + return (decl_type_t*)&type->details.alias.aliasee; +} + +static inline type_t *type_alias_get_aliasee_type(const type_t *type) +{ + decl_type_t *dt = type_alias_get_aliasee(type); + if (dt) return dt->type; + return NULL; }
static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_COCLASS); return type->details.coclass.ifaces; }
-static inline type_t *type_pointer_get_ref(const type_t *type) +static inline decl_type_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 (decl_type_t*)&type->details.pointer.ref; +} + +static inline type_t *type_pointer_get_ref_type(const type_t *type) +{ + decl_type_t *dt = type_pointer_get_ref(type); + if (dt) return dt->type; + return NULL; }
static inline unsigned char type_pointer_get_default_fc(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_POINTER); return type->details.pointer.def_fc; }
-static inline type_t *type_bitfield_get_field(const type_t *type) +static inline decl_type_t *type_bitfield_get_field(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_BITFIELD); - return type->details.bitfield.field; + return (decl_type_t*)&type->details.bitfield.field; }
static inline const expr_t *type_bitfield_get_bits(const type_t *type) { type = type_get_real_type(type); assert(type_get_type(type) == TYPE_BITFIELD); return type->details.bitfield.bits; } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 1177c1a00a..bf88d35e7c 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -35,26 +35,27 @@ typedef GUID UUID; #define TRUE 1 #define FALSE 0
typedef struct _loc_info_t loc_info_t; 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_type_t decl_type_t; typedef struct _declarator_t declarator_t; typedef struct _ifref_t ifref_t; typedef struct _typelib_entry_t typelib_entry_t; typedef struct _importlib_t importlib_t; typedef struct _importinfo_t importinfo_t; typedef struct _typelib_t typelib_t; typedef struct _user_type_t user_type_t; typedef struct _user_type_t context_handle_t; typedef struct _user_type_t generic_handle_t; -typedef struct _type_list_t type_list_t; +typedef struct _typedef_list_t typedef_list_t; typedef struct _statement_t statement_t; typedef struct _warning_t warning_t;
typedef struct list attr_list_t; typedef struct list str_list_t; typedef struct list expr_list_t; typedef struct list var_list_t; typedef struct list declarator_list_t; @@ -229,16 +230,28 @@ enum type_kind enum storage_class { STG_NONE, STG_STATIC, STG_EXTERN, STG_REGISTER, };
+enum type_qualifier +{ + TYPE_QUALIFIER_NONE, + TYPE_QUALIFIER_CONST +}; + +enum function_specifier +{ + FUNCTION_SPECIFIER_NONE, + FUNCTION_SPECIFIER_INLINE, +}; + enum statement_type { STMT_LIBRARY, STMT_DECLARATION, STMT_TYPE, STMT_TYPEREF, STMT_MODULE, STMT_TYPEDEF, @@ -288,21 +301,30 @@ struct _loc_info_t };
struct str_list_entry_t { char *str; struct list entry; };
+struct _decl_type_t +{ + struct _type_t *type; + enum storage_class stgclass; + enum type_qualifier typequalifier; + enum function_specifier funcspecifier; +}; + struct _attr_t { enum attr_type type; union { unsigned int ival; void *pval; + struct _decl_type_t dtval; } u; /* parser-internal */ struct list entry; };
struct _expr_t { enum expr_type type; const expr_t *ref; @@ -351,17 +373,17 @@ struct module_details { statement_list_t *stmts; };
struct array_details { expr_t *size_is; expr_t *length_is; - struct _type_t *elem; + struct _decl_type_t elem; unsigned int dim; unsigned char ptr_def_fc; unsigned char declptr; /* if declared as a pointer */ unsigned short ptr_tfsoff; /* offset of pointer definition for declptr */ };
struct coclass_details { @@ -371,26 +393,31 @@ struct coclass_details struct basic_details { enum type_basic_type type; int sign; };
struct pointer_details { - struct _type_t *ref; + struct _decl_type_t ref; unsigned char def_fc; };
struct bitfield_details { - struct _type_t *field; + struct _decl_type_t field; const expr_t *bits; };
+struct typedef_details +{ + struct _decl_type_t aliasee; +}; + #define HASHMAX 64
struct namespace { const char *name; struct namespace *parent; struct list entry; struct list children; struct rtype *type_hash[HASHMAX]; @@ -426,38 +453,38 @@ struct _type_t { 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 typedef_details alias; } 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; loc_info_t loc_info; unsigned int ignore : 1; unsigned int defined : 1; unsigned int written : 1; unsigned int user_types_registered : 1; unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */ unsigned int checked : 1; unsigned int is_alias : 1; /* is the type an alias? */ };
+ struct _var_t { char *name; - type_t *type; + decl_type_t decltype; 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;
/* parser-internal */ struct list entry; }; @@ -518,32 +545,37 @@ struct _typelib_t { statement_list_t *stmts; };
struct _user_type_t { struct list entry; const char *name; };
+struct _typedef_list_t { + var_t *var; + struct _typedef_list_t *next; +}; + struct _type_list_t { type_t *type; struct _type_list_t *next; };
struct _statement_t { struct list entry; enum statement_type type; union { ifref_t iface; type_t *type; const char *str; var_t *var; typelib_t *lib; - type_list_t *type_list; + typedef_list_t *typedef_list; } u; };
struct _warning_t { int num; struct list entry; };
@@ -591,18 +623,18 @@ 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) + if (stmt->type == STMT_DECLARATION && stmt->u.var->decltype.stgclass == STG_NONE && \ + type_get_type_detect_alias(stmt->u.var->decltype.type) == TYPE_FUNCTION)
static inline int statements_has_func(const statement_list_t *stmts) { const statement_t *stmt; int has_func = 0; STATEMENTS_FOR_EACH_FUNC(stmt, stmts) { has_func = 1; @@ -611,9 +643,18 @@ static inline int statements_has_func(const statement_list_t *stmts) return has_func; }
static inline int is_global_namespace(const struct namespace *namespace) { return !namespace->name; }
+static inline decl_type_t* init_decltype(decl_type_t *decltype, type_t *type) +{ + decltype->type = type; + decltype->stgclass=STG_NONE; + decltype->typequalifier=TYPE_QUALIFIER_NONE; + decltype->funcspecifier=FUNCTION_SPECIFIER_NONE; + return decltype; +} + #endif diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 4dcbc03702..24d5c9a368 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -857,26 +857,26 @@ static int encode_type( case VT_LPSTR: case VT_LPWSTR: *encoded_type = 0xfffe0000 | vt; break;
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; } /* if no type found then it must be void */ 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 */ if(next_vt == VT_DISPATCH || next_vt == VT_UNKNOWN) { chat("encode_type: skipping ptr\n"); *encoded_type = target_type; *decoded_size = child_size; break; @@ -907,20 +907,20 @@ static int encode_type( *encoded_type = typeoffset;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; break; }
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) { typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; if (((typedata[0] & 0xffff) == VT_SAFEARRAY) && (typedata[1] == target_type)) break; }
if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { @@ -963,17 +963,17 @@ static int encode_type( type->name, importinfo->importlib->name); alloc_importinfo(typelib, importinfo); typeinfo_offset = importinfo->offset | 0x1; } 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); + type = type_alias_get_aliasee_type(type);
chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n", type->name, type_get_type(type));
switch (type_get_type(type)) { case TYPE_STRUCT: add_structure_typeinfo(typelib, type); @@ -1051,32 +1051,32 @@ static int encode_var( if (is_array(type) && !type_array_is_decl_as_ptr(type)) { int num_dims, elements = 1, arrayoffset; type_t *atype; int *arraydata;
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); encode_var(typelib, atype, var, &target_type, NULL); arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0); arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
arraydata[0] = target_type; arraydata[1] = num_dims; arraydata[1] |= ((num_dims * 2 * sizeof(int)) << 16);
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; arraydata += 2; elements *= type_array_get_dim(atype); }
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); @@ -1088,17 +1088,17 @@ static int encode_var( *encoded_type = typeoffset; *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; return 0; }
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) { chat("encode_var: skipping ptr\n"); *encoded_type = target_type; *decoded_size = child_size; return 0; } @@ -1109,17 +1109,17 @@ static int encode_var( }
if (typeoffset == typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length) { int mix_field;
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]; mix_field = ((typedata[0] >> 16) == 0x7fff)? 0x7fff: 0x7ffe; }
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; @@ -1199,17 +1199,17 @@ static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *e chat("default value '%s'\n", expr->u.sval); write_string_value(typelib, out, expr->u.sval); return; }
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) warning("non-null pointer default value\n"); } else { vt = get_type_vt(type); switch(vt) { case VT_I2: @@ -1296,18 +1296,18 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) break; }
if (is_local( func->attrs )) { chat("add_func_desc: skipping local function\n"); return S_FALSE; }
- if (type_get_function_args(func->type)) - LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry ) + if (type_get_function_args(func->decltype.type)) + LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->decltype.type), var_t, entry ) { num_params++; if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { if(attr->type == ATTR_DEFAULTVALUE) num_defaults++; else if(attr->type == ATTR_OPTIONAL) num_optional++; } @@ -1439,17 +1439,17 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] &= 0xffff; typeinfo->func_data[(typeinfo->func_offsets[i] >> 2) + 1 + 4] |= (index << 16); break; } }
/* 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->decltype.type), func, &typedata[1], &decoded_size); typedata[2] = funcflags; typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind; if(num_defaults) typedata[4] |= 0x1000; if(entry_is_ord) typedata[4] |= 0x2000; typedata[5] = (num_optional << 16) | num_params;
@@ -1466,34 +1466,34 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) case 2: typedata[7] = help_string_offset; case 1: typedata[6] = help_context; case 0: break; default: warning("unknown number of optional attrs\n"); }
- if (type_get_function_args(func->type)) + if (type_get_function_args(func->decltype.type)) { i = 0; - LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry ) + LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->decltype.type), var_t, entry ) { int paramflags = 0; int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; int *defaultdata = num_defaults ? typedata + 6 + extra_attr + i : NULL;
if(defaultdata) *defaultdata = -1;
- encode_var(typeinfo->typelib, arg->type, arg, paramdata, &decoded_size); + encode_var(typeinfo->typelib, arg->decltype.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->decltype.type, (expr_t *)attr->u.pval, defaultdata); break; } case ATTR_IN: paramflags |= 0x01; /* PARAMFLAG_FIN */ break; case ATTR_OPTIONAL: paramflags |= 0x10; /* PARAMFLAG_FOPT */ break; @@ -1567,20 +1567,20 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) if(typeinfo->typekind == TKIND_MODULE) namedata[9] |= 0x10; } else namedata[9] &= ~0x10;
if(typeinfo->typekind == TKIND_MODULE) namedata[9] |= 0x20;
- if (type_get_function_args(func->type)) + if (type_get_function_args(func->decltype.type)) { i = 0; - LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->type), var_t, entry ) + LIST_FOR_EACH_ENTRY( arg, type_get_function_args(func->decltype.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 */)) { int *paramdata = typedata + 6 + extra_attr + (num_defaults ? num_params : 0) + i * 3; offset = ctl2_alloc_name(typeinfo->typelib, arg->name); paramdata[1] = offset; } @@ -1692,18 +1692,18 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) typeinfo->var_offsets = xrealloc(typeinfo->var_offsets, typeinfo->vars_allocated * sizeof(int)); } /* update the index data */ typeinfo->var_indices[var_num] = id; typeinfo->var_names[var_num] = -1; 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->decltype.type, &var_alignment); + encode_var(typeinfo->typelib, var->decltype.type, var, &typedata[1], &var_type_size);
/* pad out starting position to data width */ typeinfo->datawidth += var_alignment - 1; typeinfo->datawidth &= ~(var_alignment - 1);
switch(typeinfo->typekind) { case TKIND_ENUM: write_int_value(typeinfo->typelib, &typedata[4], VT_I4, var->eval->cval); @@ -2176,17 +2176,17 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef) msft_typeinfo_t *msft_typeinfo = NULL; int datatype1, datatype2, duplicate = 0; unsigned int size, alignment = 0; type_t *type;
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) { tdef->typelib_idx = typelib->typelib_header.nrtypeinfos; msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ALIAS, tdef->name, tdef->attrs); } else duplicate = 1; @@ -2352,24 +2352,24 @@ static void add_entry(msft_typelib_t *typelib, const statement_t *stmt) case STMT_DECLARATION: /* not included in typelib */ break; case STMT_IMPORTLIB: /* not processed here */ break; case STMT_TYPEDEF: { - const type_list_t *type_entry = stmt->u.type_list; - for (; type_entry; type_entry = type_entry->next) { + const typedef_list_t *typedef_entry = stmt->u.typedef_list; + for (; typedef_entry; typedef_entry = typedef_entry->next) { /* if the type is public then add the typedef, otherwise attempt * to add the aliased type */ - if (is_attr(type_entry->type->attrs, ATTR_PUBLIC)) - add_typedef_typeinfo(typelib, type_entry->type); + if (is_attr(typedef_entry->var->decltype.type->attrs, ATTR_PUBLIC)) + add_typedef_typeinfo(typelib, typedef_entry->var->decltype.type); else - add_type_typeinfo(typelib, type_alias_get_aliasee(type_entry->type)); + add_type_typeinfo(typelib, type_alias_get_aliasee_type(typedef_entry->var->decltype.type)); } break; } case STMT_MODULE: add_module_typeinfo(typelib, stmt->u.type); break; case STMT_TYPE: case STMT_TYPEREF: