From 67ac03ae4e011ec03fddaf5fe3286ecf2cb89759 Mon Sep 17 00:00:00 2001 From: Rob Shearman Date: Mon, 5 Jan 2009 23:34:58 +0000 Subject: [PATCH] widl: Add a new function, type_pointer_get_ref. Use it for retrieving the type that a pointer refers to. --- tools/widl/expr.c | 2 +- tools/widl/header.c | 30 +++++++++++------ tools/widl/header.h | 4 +-- tools/widl/parser.y | 14 ++++---- tools/widl/proxy.c | 8 ++--- tools/widl/typegen.c | 74 ++++++++++++++++++++++++----------------- tools/widl/typelib.c | 9 ++++- tools/widl/typetree.h | 6 ++++ tools/widl/write_msft.c | 12 ++++--- 9 files changed, 99 insertions(+), 60 deletions(-) diff --git a/tools/widl/expr.c b/tools/widl/expr.c index 2fd4fa6b490..7f0e26d588c 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -469,7 +469,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc case EXPR_PPTR: result = resolve_expression(expr_loc, cont_type, e->ref); if (result.type && is_ptr(result.type)) - result.type = result.type->ref; + result.type = type_pointer_get_ref(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 " : "", diff --git a/tools/widl/header.c b/tools/widl/header.c index 91212612f5c..7c784fad66a 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -65,7 +65,7 @@ int is_ptrchain_attr(const var_t *var, enum attr_type t) else if (type_is_alias(type)) type = type->orig; else if (is_ptr(type)) - type = type->ref; + type = type_pointer_get_ref(type); else return 0; } } @@ -253,9 +253,9 @@ void write_type_left(FILE *h, type_t *t, int declonly) case RPC_FC_UP: case RPC_FC_FP: case RPC_FC_OP: - write_type_left(h, t->ref, declonly); - fprintf(h, "%s*", needs_space_after(t->ref) ? " " : ""); - if (is_ptr(t) && is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const "); + write_type_left(h, type_pointer_get_ref(t), declonly); + fprintf(h, "%s*", needs_space_after(type_pointer_get_ref(t)) ? " " : ""); + if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const "); break; case RPC_FC_CARRAY: case RPC_FC_CVARRAY: @@ -291,7 +291,7 @@ void write_type_v(FILE *h, type_t *t, int is_field, int declonly, if (!h) return; - for (pt = t; is_ptr(pt); pt = pt->ref, ptr_level++) + for (pt = t; is_ptr(pt); pt = type_pointer_get_ref(pt), ptr_level++) ; if (pt->type == RPC_FC_FUNCTION) { @@ -378,10 +378,11 @@ void check_for_additional_prototype_types(const var_list_t *list) if (!list) return; LIST_FOR_EACH_ENTRY( v, list, const var_t, entry ) { - type_t *type; - for (type = v->type; type; type = type_is_alias(type) ? type->orig : type->ref) { + type_t *type = v->type; + if (!type) continue; + for (;;) { const char *name = type->name; - if (type->user_types_registered) continue; + if (type->user_types_registered) break; type->user_types_registered = 1; if (is_attr(type->attrs, ATTR_CONTEXTHANDLE)) { if (!context_handle_registered(name)) @@ -425,6 +426,15 @@ void check_for_additional_prototype_types(const var_list_t *list) vars = type_union_get_cases(type); check_for_additional_prototype_types(vars); } + + if (type_is_alias(type)) + type = type->orig; + else if (is_ptr(type)) + type = type_pointer_get_ref(type); + else if (is_array(type)) + type = type_array_get_element(type); + else + break; } } } @@ -482,7 +492,7 @@ int is_const_decl(const var_t *var) if (is_attr(t->attrs, ATTR_CONST)) return TRUE; else if (is_ptr(t)) - t = t->ref; + t = type_pointer_get_ref(t); else break; } return FALSE; @@ -541,7 +551,7 @@ const var_t* get_explicit_handle_var(const var_t *func) const type_t* get_explicit_generic_handle_type(const var_t* var) { const type_t *t; - for (t = var->type; is_ptr(t); t = t->ref) + for (t = var->type; is_ptr(t); t = type_pointer_get_ref(t)) if (t->type != RPC_FC_BIND_PRIMITIVE && is_attr(t->attrs, ATTR_HANDLE)) return t; return NULL; diff --git a/tools/widl/header.h b/tools/widl/header.h index 876fa42f253..6ac7cb0ae65 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -58,7 +58,7 @@ extern int is_const_decl(const var_t *var); static inline int last_ptr(const type_t *type) { - return is_ptr(type) && !is_declptr(type->ref); + return is_ptr(type) && !is_declptr(type_pointer_get_ref(type)); } static inline int last_array(const type_t *type) @@ -75,7 +75,7 @@ static inline int is_string_type(const attr_list_t *attrs, const type_t *type) static inline int is_context_handle(const type_t *type) { const type_t *t; - for (t = type; is_ptr(t); t = t->ref) + for (t = type; is_ptr(t); t = type_pointer_get_ref(t)) if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) return 1; return 0; diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 07cbc5eebdb..a3af087854b 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1419,7 +1419,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, { type_t *t; /* move inline attribute from return type node to function node */ - for (t = func_type; is_ptr(t); t = t->ref) + for (t = func_type; is_ptr(t); t = type_pointer_get_ref(t)) ; t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE); } @@ -1556,13 +1556,13 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, type_t *ft, *t; type_t *return_type = v->type; v->type = func_type; - for (ft = v->type; is_ptr(ft); ft = ft->ref) + for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft)) ; assert(ft->type == RPC_FC_FUNCTION); ft->ref = return_type; /* move calling convention attribute, if present, from pointer nodes to * function node */ - for (t = v->type; is_ptr(t); t = t->ref) + for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t)) ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV); if (is_object_interface && !is_attr(ft->attrs, ATTR_CALLCONV)) { @@ -1574,7 +1574,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl, else { type_t *t; - for (t = v->type; is_ptr(t); t = t->ref) + for (t = v->type; is_ptr(t); t = type_pointer_get_ref(t)) if (is_attr(t->attrs, ATTR_CALLCONV)) error_loc("calling convention applied to non-function-pointer type\n"); } @@ -1826,7 +1826,7 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at unsigned char c; while (is_ptr(t)) - t = t->ref; + t = type_pointer_get_ref(t); c = t->type; if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) @@ -2281,7 +2281,7 @@ static int is_ptr_guid_type(const type_t *type) /* second, make sure it is a pointer to something of size sizeof(GUID), * i.e. 16 bytes */ - return (type_memsize(type->ref, &align) == 16); + return (type_memsize(type_pointer_get_ref(type), &align) == 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) @@ -2446,7 +2446,7 @@ static void check_remoting_args(const var_t *func) else if (is_ptr(type)) { ptr_level++; - type = type->ref; + type = type_pointer_get_ref(type); } else break; diff --git a/tools/widl/proxy.c b/tools/widl/proxy.c index 387b4afc181..39f4c2c31f5 100644 --- a/tools/widl/proxy.c +++ b/tools/widl/proxy.c @@ -164,10 +164,10 @@ int cant_be_null(const var_t *v) if (is_user_type(type)) return 0; - if (! attrs && type) + if (!attrs && is_ptr(type)) { attrs = type->attrs; - type = type->ref; + type = type_pointer_get_ref(type); } while (attrs) @@ -180,10 +180,10 @@ int cant_be_null(const var_t *v) if (t == RPC_FC_RP) return 1; - if (type) + if (is_ptr(type)) { attrs = type->attrs; - type = type->ref; + type = type_pointer_get_ref(type); } else attrs = NULL; diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 8135186d56e..67a828b9172 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -152,7 +152,7 @@ static int get_struct_type(const type_t *type) continue; } - if (is_array(field->type->ref)) + if (is_array(type_array_get_element(field->type))) return RPC_FC_BOGUS_STRUCT; if (type_array_has_conformance(field->type)) @@ -205,7 +205,7 @@ static int get_struct_type(const type_t *type) return RPC_FC_BOGUS_STRUCT; /* pointers to interfaces aren't really pointers and have to be * marshalled specially so they make the structure complex */ - if (t->ref->type == RPC_FC_IP) + if (type_pointer_get_ref(t)->type == RPC_FC_IP) return RPC_FC_BOGUS_STRUCT; has_pointer = 1; break; @@ -298,7 +298,8 @@ static int get_array_type(const type_t *type) /* FC_RP should be above, but widl overuses these, and will break things. */ case RPC_FC_UP: case RPC_FC_RP: - if (rt->ref->type == RPC_FC_IP) return RPC_FC_BOGUS_ARRAY; + if (type_pointer_get_ref(rt)->type == RPC_FC_IP) + return RPC_FC_BOGUS_ARRAY; break; } @@ -483,13 +484,13 @@ static int is_embedded_complex(const type_t *type) { unsigned char tc = type->type; return is_struct(tc) || is_union(tc) || is_array(type) || is_user_type(type) - || (is_ptr(type) && type->ref->type == RPC_FC_IP); + || (is_ptr(type) && type_pointer_get_ref(type)->type == RPC_FC_IP); } static const char *get_context_handle_type_name(const type_t *type) { const type_t *t; - for (t = type; is_ptr(t); t = t->ref) + for (t = type; is_ptr(t); t = type_pointer_get_ref(t)) if (is_attr(t->attrs, ATTR_CONTEXTHANDLE)) return t->name; assert(0); @@ -1104,9 +1105,9 @@ void write_full_pointer_free(FILE *file, int indent, const var_t *func) static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size_t offset) { - short absoff = type->ref->typestring_offset; + short absoff = type_pointer_get_ref(type)->typestring_offset; short reloff = absoff - (offset + 2); - int ptr_attr = is_ptr(type->ref) ? 0x10 : 0x0; + int ptr_attr = is_ptr(type_pointer_get_ref(type)) ? 0x10 : 0x0; print_file(file, 2, "0x%02x, 0x%x,\t/* %s */\n", type->type, ptr_attr, string_of_type(type->type)); @@ -1117,7 +1118,7 @@ static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size static unsigned int write_simple_pointer(FILE *file, const type_t *type) { - unsigned char fc = type->ref->type; + unsigned char fc = type_pointer_get_ref(type)->type; /* 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(type->attrs, type)) @@ -1143,9 +1144,9 @@ static size_t write_pointer_tfs(FILE *file, type_t *type, unsigned int *typestri print_start_tfs_comment(file, type, offset); update_tfsoff(type, offset, file); - if (type->ref->typestring_offset) + if (type_pointer_get_ref(type)->typestring_offset) *typestring_offset += write_nonsimple_pointer(file, type, offset); - else if (is_base_type(type->ref->type)) + else if (is_base_type(type_pointer_get_ref(type)->type)) *typestring_offset += write_simple_pointer(file, type); return offset; @@ -1392,7 +1393,7 @@ static int write_pointer_description_offsets( int written = 0; unsigned int align; - if (is_ptr(type) && type->ref->type != RPC_FC_IP) + if (is_ptr(type) && type_pointer_get_ref(type)->type != RPC_FC_IP) { if (offset_in_memory && offset_in_buffer) { @@ -1414,7 +1415,8 @@ static int write_pointer_description_offsets( if (is_string_type(attrs, type)) write_string_tfs(file, NULL, type, NULL, typestring_offset); - else if (processed(type->ref) || is_base_type(type->ref->type)) + else if (processed(type_pointer_get_ref(type)) || + is_base_type(type_pointer_get_ref(type)->type)) write_pointer_tfs(file, type, typestring_offset); else error("write_pointer_description_offsets: type format string unknown\n"); @@ -1749,7 +1751,10 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, start_offset = *typestring_offset; update_tfsoff(type, start_offset, file); - rtype = type->ref->type; + if (is_array(type)) + rtype = type_array_get_element(type)->type; + else + rtype = type_pointer_get_ref(type)->type; if ((rtype != RPC_FC_BYTE) && (rtype != RPC_FC_CHAR) && (rtype != RPC_FC_WCHAR)) { @@ -2324,7 +2329,7 @@ static size_t write_ip_tfs(FILE *file, const attr_list_t *attrs, type_t *type, } else { - const type_t *base = is_ptr(type) ? type->ref : type; + const type_t *base = is_ptr(type) ? type_pointer_get_ref(type) : type; const UUID *uuid = get_attrp(base->attrs, ATTR_UUID); if (! uuid) @@ -2476,7 +2481,7 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const var_t *fu size_t start_offset = *typeformat_offset; int in_attr = is_attr(var->attrs, ATTR_IN); int out_attr = is_attr(var->attrs, ATTR_OUT); - const type_t *base = type->ref; + const type_t *base = type_pointer_get_ref(type); if (base->type == RPC_FC_IP || (base->type == 0 @@ -2501,7 +2506,9 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const var_t *fu assert(is_ptr(type)); - offset = write_typeformatstring_var(file, indent, func, type->ref, var, typeformat_offset); + offset = write_typeformatstring_var(file, indent, func, + type_pointer_get_ref(type), var, + typeformat_offset); if (file) fprintf(file, "/* %2u */\n", *typeformat_offset); return write_pointer_only_tfs(file, var->attrs, type->type, @@ -2524,7 +2531,7 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty } else if (is_ptr(type)) { - type_t *ref = type->ref; + type_t *ref = type_pointer_get_ref(type); if (ref->type == RPC_FC_IP || (ref->type == 0 @@ -2705,14 +2712,15 @@ static unsigned int get_required_buffer_size_type( return fields_memsize(type_struct_get_fields(type), alignment); case RPC_FC_RP: - return - is_base_type( type->ref->type ) || get_struct_type(type->ref) == RPC_FC_STRUCT - ? get_required_buffer_size_type( type->ref, name, alignment ) - : 0; + { + const type_t *ref = type_pointer_get_ref(type); + return is_base_type( ref->type ) || get_struct_type(ref) == RPC_FC_STRUCT ? + get_required_buffer_size_type( ref, name, alignment ) : 0; + } case RPC_FC_SMFARRAY: case RPC_FC_LGFARRAY: - return type_array_get_dim(type) * get_required_buffer_size_type(type->ref, name, alignment); + return type_array_get_dim(type) * get_required_buffer_size_type(type_array_get_element(type), name, alignment); default: return 0; @@ -2823,7 +2831,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL) return; - rtype = is_ptr(type) ? type->ref->type : type->type; + rtype = is_ptr(type) ? type_pointer_get_ref(type)->type : type->type; switch (rtype) { @@ -2876,7 +2884,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, if (phase == PHASE_MARSHAL) { print_file(file, indent, "*("); - write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); if (is_ptr(type)) fprintf(file, " *)__frame->_StubMsg.Buffer = *"); else @@ -2887,7 +2895,7 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, else if (phase == PHASE_UNMARSHAL) { print_file(file, indent, "if (__frame->_StubMsg.Buffer + sizeof("); - write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); fprintf(file, ") > __frame->_StubMsg.BufferEnd)\n"); print_file(file, indent, "{\n"); print_file(file, indent + 1, "RpcRaiseException(RPC_X_BAD_STUB_DATA);\n"); @@ -2901,12 +2909,12 @@ void print_phase_basetype(FILE *file, int indent, const char *local_var_prefix, fprintf(file, " = ("); else fprintf(file, " = *("); - write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); fprintf(file, " *)__frame->_StubMsg.Buffer;\n"); } print_file(file, indent, "__frame->_StubMsg.Buffer += sizeof("); - write_type_decl(file, is_ptr(type) ? type->ref : type, NULL); + write_type_decl(file, is_ptr(type) ? type_pointer_get_ref(type) : type, NULL); fprintf(file, ");\n"); } @@ -2989,7 +2997,7 @@ static void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char break; } else if (is_ptr(type)) - type = type->ref; + type = type_pointer_get_ref(type); else break; } @@ -3162,7 +3170,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const } else { - const type_t *ref = type->ref; + const type_t *ref = type_pointer_get_ref(type); if (type->type == RPC_FC_RP && is_base_type(ref->type)) { if (phase != PHASE_FREE) @@ -3311,9 +3319,13 @@ void declare_stub_args( FILE *file, int indent, const var_t *func ) { if (!in_attr && !is_conformant_array(var->type) && !is_string) { + type_t *type_to_print; print_file(file, indent, ""); - write_type_decl(file, var->type->declarray ? var->type : var->type->ref, - "_W%u", i++); + if (var->type->declarray) + type_to_print = var->type; + else + type_to_print = type_pointer_get_ref(var->type); + write_type_decl(file, type_to_print, "_W%u", i++); fprintf(file, ";\n"); } diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c index 979d3c73d21..d8ccd0ed151 100644 --- a/tools/widl/typelib.c +++ b/tools/widl/typelib.c @@ -124,12 +124,19 @@ static unsigned short builtin_vt(const type_t *t) return kwp->vt; } if (is_string_type (t->attrs, t)) - switch (t->ref->type) + { + unsigned char fc; + if (is_array(t)) + fc = type_array_get_element(t)->type; + else + fc = type_pointer_get_ref(t)->type; + switch (fc) { case RPC_FC_CHAR: return VT_LPSTR; case RPC_FC_WCHAR: return VT_LPWSTR; default: break; } + } return 0; } diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index 187fee67937..200d17de75c 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -166,4 +166,10 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type) return type->details.coclass.ifaces; } +static inline type_t *type_pointer_get_ref(const type_t *type) +{ + assert(is_ptr(type)); + return type->ref; +} + #endif /* WIDL_TYPE_TREE_H */ diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index 393e97efac7..380710a93d1 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -876,8 +876,8 @@ static int encode_type( case VT_PTR: { int next_vt; - for(next_vt = 0; type->ref; type = type->ref) { - next_vt = get_type_vt(type->ref); + for(next_vt = 0; is_ptr(type); type = type_pointer_get_ref(type)) { + next_vt = get_type_vt(type_pointer_get_ref(type)); if (next_vt != 0) break; } @@ -885,7 +885,8 @@ static int encode_type( if (next_vt == 0) next_vt = VT_VOID; - encode_type(typelib, next_vt, type->ref, &target_type, NULL, NULL, &child_size); + encode_type(typelib, next_vt, type_pointer_get_ref(type), + &target_type, NULL, NULL, &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) { @@ -1115,7 +1116,10 @@ static int encode_var( vt = get_type_vt(type); if (vt == VT_PTR) { - int skip_ptr = encode_var(typelib, type->ref, var, &target_type, NULL, NULL, &child_size); + type_t *ref = is_ptr(type) ? + type_pointer_get_ref(type) : type_array_get_element(type); + int skip_ptr = encode_var(typelib, ref, var, + &target_type, NULL, NULL, &child_size); if(skip_ptr == 2) { chat("encode_var: skipping ptr\n");