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:
Richard Pospesel richard@torproject.org wrote:
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.
You should try to split the patch into smaller parts and avoid unnecessary renaming things and white space changes. At the existing state the patch is absolutely not manageable. Also it looks like that you have some strange 'git diff' setting that makes the patch alomost 40% larger because of huge diff contexts.
I will make these suggested changes regarding white space, diff context, and renames (an artifact of the dev process, but unnecessary), but be warned, the bulk of this change needs to be in the same patch. This is a major refactor which needs to touch a lot of code all at once, or else we end up with invalid headers, typelibs, etc.
I can extract the actual fixes for duplicate type detection and a missing inline specifier (which depend on this refactor), but they are very few lines compared to the rest.
Anyway, I'm pospeselr on #winehackers if you wish to discuss in real-time.
best, -Richard
On 5/14/19 11:56 PM, Dmitry Timoshkov wrote:
Richard Pospesel richard@torproject.org wrote:
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.
You should try to split the patch into smaller parts and avoid unnecessary renaming things and white space changes. At the existing state the patch is absolutely not manageable. Also it looks like that you have some strange 'git diff' setting that makes the patch alomost 40% larger because of huge diff contexts.