widl: Add a new function, type_pointer_get_ref.

Use it for retrieving the type that a pointer refers to.
This commit is contained in:
Rob Shearman 2009-01-05 23:34:58 +00:00 committed by Alexandre Julliard
parent 2b87d269e1
commit 67ac03ae4e
9 changed files with 99 additions and 60 deletions

View File

@ -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 " : "",

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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");