widl: Access array type properties through accessors instead of getting them directly.

Store array type properties in the details union to save a bit of
memory and to make the general properties more obvious.
This commit is contained in:
Rob Shearman 2009-01-05 23:33:36 +00:00 committed by Alexandre Julliard
parent 901a42b7f9
commit 200ec53835
6 changed files with 84 additions and 45 deletions

View File

@ -118,7 +118,7 @@ int is_conformant_array(const type_t *t)
{ {
return t->type == RPC_FC_CARRAY return t->type == RPC_FC_CARRAY
|| t->type == RPC_FC_CVARRAY || t->type == RPC_FC_CVARRAY
|| (t->type == RPC_FC_BOGUS_ARRAY && t->size_is); || (t->type == RPC_FC_BOGUS_ARRAY && type_array_has_conformance(t));
} }
void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid) void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *uuid)
@ -276,7 +276,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
t = t->ref; t = t->ref;
} }
for ( ; t->declarray; t = t->ref) for ( ; t->declarray; t = t->ref)
fprintf(h, "[%lu]", t->dim); fprintf(h, "[%lu]", type_array_get_dim(t));
} }
} }

View File

@ -1300,9 +1300,6 @@ type_t *make_type(unsigned char type, type_t *ref)
t->orig = NULL; t->orig = NULL;
memset(&t->details, 0, sizeof(t->details)); memset(&t->details, 0, sizeof(t->details));
t->ifaces = NULL; t->ifaces = NULL;
t->dim = 0;
t->size_is = NULL;
t->length_is = NULL;
t->typestring_offset = 0; t->typestring_offset = 0;
t->ptrdesc = 0; t->ptrdesc = 0;
t->declarray = FALSE; t->declarray = FALSE;
@ -1498,7 +1495,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
} }
v->type->declarray = TRUE; v->type->declarray = TRUE;
v->type->dim = dim->cval; v->type->details.array.dim = dim->cval;
} }
ptype = &v->type; ptype = &v->type;
@ -1517,7 +1514,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
error_loc("%s: size_is attribute applied to illegal type\n", v->name); error_loc("%s: size_is attribute applied to illegal type\n", v->name);
atype->type = RPC_FC_CARRAY; atype->type = RPC_FC_CARRAY;
atype->size_is = dim; atype->details.array.size_is = dim;
} }
ptype = &(*ptype)->ref; ptype = &(*ptype)->ref;
@ -1542,7 +1539,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
else else
error_loc("%s: length_is attribute applied to illegal type\n", v->name); error_loc("%s: length_is attribute applied to illegal type\n", v->name);
atype->length_is = dim; atype->details.array.length_is = dim;
} }
ptype = &(*ptype)->ref; ptype = &(*ptype)->ref;

View File

@ -155,14 +155,14 @@ static int get_struct_type(const type_t *type)
if (is_array(field->type->ref)) if (is_array(field->type->ref))
return RPC_FC_BOGUS_STRUCT; return RPC_FC_BOGUS_STRUCT;
if (is_conformant_array(field->type)) if (type_array_has_conformance(field->type))
{ {
has_conformance = 1; has_conformance = 1;
if (field->type->declarray && list_next(fields, &field->entry)) if (field->type->declarray && list_next(fields, &field->entry))
error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n", error_loc("field '%s' deriving from a conformant array must be the last field in the structure\n",
field->name); field->name);
} }
if (field->type->length_is) if (type_array_has_variance(field->type))
has_variance = 1; has_variance = 1;
t = field->type->ref; t = field->type->ref;
@ -306,7 +306,7 @@ static int get_array_type(const type_t *type)
{ {
unsigned int align = 0; unsigned int align = 0;
size_t size = type_memsize(type, &align); size_t size = type_memsize(type, &align);
if (size * type->dim <= 0xffff) if (size * type_array_get_dim(type) <= 0xffff)
return (type->type == RPC_FC_LGFARRAY) ? RPC_FC_SMFARRAY : RPC_FC_SMVARRAY; return (type->type == RPC_FC_LGFARRAY) ? RPC_FC_SMFARRAY : RPC_FC_SMVARRAY;
} }
} }
@ -1066,10 +1066,10 @@ size_t type_memsize(const type_t *t, unsigned int *align)
case RPC_FC_SMVARRAY: case RPC_FC_SMVARRAY:
case RPC_FC_LGVARRAY: case RPC_FC_LGVARRAY:
case RPC_FC_BOGUS_ARRAY: case RPC_FC_BOGUS_ARRAY:
size = t->dim * type_memsize(t->ref, align); size = type_array_get_dim(t) * type_memsize(t->ref, align);
break; break;
default: default:
error("type_memsize: Unknown type %d\n", t->type); error("type_memsize: Unknown type 0x%x\n", t->type);
size = 0; size = 0;
} }
@ -1494,7 +1494,7 @@ static int write_fixed_array_pointer_descriptions(
print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", RPC_FC_FIXED_REPEAT); print_file(file, 2, "0x%02x, /* FC_FIXED_REPEAT */\n", RPC_FC_FIXED_REPEAT);
print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD); print_file(file, 2, "0x%02x, /* FC_PAD */\n", RPC_FC_PAD);
print_file(file, 2, "NdrFcShort(0x%x), /* Iterations = %d */\n", type->dim, type->dim); print_file(file, 2, "NdrFcShort(0x%x), /* Iterations = %d */\n", type_array_get_dim(type), type_array_get_dim(type));
print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size); print_file(file, 2, "NdrFcShort(0x%x), /* Increment = %d */\n", increment_size, increment_size);
print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory); print_file(file, 2, "NdrFcShort(0x%x), /* Offset to array = %d */\n", *offset_in_memory, *offset_in_memory);
print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count); print_file(file, 2, "NdrFcShort(0x%x), /* Number of pointers = %d */\n", pointer_count, pointer_count);
@ -1550,7 +1550,7 @@ static int write_conformant_array_pointer_descriptions(
unsigned int align; unsigned int align;
int pointer_count = 0; int pointer_count = 0;
if (is_conformant_array(type) && !type->length_is) if (is_conformant_array(type) && !type_array_has_variance(type))
{ {
unsigned int temp = 0; unsigned int temp = 0;
/* unfortunately, this needs to be done in two passes to avoid /* unfortunately, this needs to be done in two passes to avoid
@ -1595,7 +1595,7 @@ static int write_varying_array_pointer_descriptions(
unsigned int align; unsigned int align;
int pointer_count = 0; int pointer_count = 0;
if (is_array(type) && type->length_is) if (is_array(type) && type_array_has_variance(type))
{ {
unsigned int temp = 0; unsigned int temp = 0;
/* unfortunately, this needs to be done in two passes to avoid /* unfortunately, this needs to be done in two passes to avoid
@ -1633,7 +1633,7 @@ static int write_varying_array_pointer_descriptions(
{ {
size_t padding; size_t padding;
if (is_array(v->type) && v->type->length_is) if (is_array(v->type) && type_array_has_variance(v->type))
{ {
*offset_in_buffer = ROUND_SIZE(*offset_in_buffer, 4); *offset_in_buffer = ROUND_SIZE(*offset_in_buffer, 4);
/* skip over variance and offset in buffer */ /* skip over variance and offset in buffer */
@ -1758,10 +1758,12 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
if (type->declarray && !is_conformant_array(type)) if (type->declarray && !is_conformant_array(type))
{ {
unsigned long dim = type_array_get_dim(type);
/* FIXME: multi-dimensional array */ /* FIXME: multi-dimensional array */
if (0xffffuL < type->dim) if (0xffffuL < dim)
error("array size for parameter %s exceeds %u bytes by %lu bytes\n", error("array size for parameter %s exceeds %u bytes by %lu bytes\n",
name, 0xffffu, type->dim - 0xffffu); name, 0xffffu, dim - 0xffffu);
if (rtype == RPC_FC_CHAR) if (rtype == RPC_FC_CHAR)
WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset); WRITE_FCTYPE(file, FC_CSTRING, *typestring_offset);
@ -1770,12 +1772,12 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD); print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2; *typestring_offset += 2;
print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", type->dim, type->dim); print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", dim, dim);
*typestring_offset += 2; *typestring_offset += 2;
return start_offset; return start_offset;
} }
else if (type->size_is) else if (is_conformant_array(type))
{ {
unsigned int align = 0; unsigned int align = 0;
@ -1791,7 +1793,7 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
(type->declarray && current_structure (type->declarray && current_structure
? type_memsize(current_structure, &align) ? type_memsize(current_structure, &align)
: 0), : 0),
type, type->size_is); type, type_array_get_conformance(type));
return start_offset; return start_offset;
} }
@ -1811,8 +1813,8 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type, static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type,
const char *name, unsigned int *typestring_offset) const char *name, unsigned int *typestring_offset)
{ {
const expr_t *length_is = type->length_is; const expr_t *length_is = type_array_get_variance(type);
const expr_t *size_is = type->size_is; const expr_t *size_is = type_array_get_conformance(type);
unsigned int align = 0; unsigned int align = 0;
size_t size; size_t size;
size_t start_offset; size_t start_offset;
@ -1866,15 +1868,16 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
{ {
unsigned int elalign = 0; unsigned int elalign = 0;
size_t elsize = type_memsize(type->ref, &elalign); size_t elsize = type_memsize(type->ref, &elalign);
unsigned long dim = type_array_get_dim(type);
if (real_type == RPC_FC_LGVARRAY) if (real_type == RPC_FC_LGVARRAY)
{ {
print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", type->dim, type->dim); print_file(file, 2, "NdrFcLong(0x%x),\t/* %lu */\n", dim, dim);
*typestring_offset += 4; *typestring_offset += 4;
} }
else else
{ {
print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", type->dim, type->dim); print_file(file, 2, "NdrFcShort(0x%x),\t/* %lu */\n", dim, dim);
*typestring_offset += 2; *typestring_offset += 2;
} }
@ -1902,7 +1905,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
} }
else else
{ {
unsigned int dim = size_is ? 0 : type->dim; unsigned int dim = size_is ? 0 : type_array_get_dim(type);
print_file(file, 2, "NdrFcShort(0x%x),\t/* %u */\n", dim, dim); print_file(file, 2, "NdrFcShort(0x%x),\t/* %u */\n", dim, dim);
*typestring_offset += 2; *typestring_offset += 2;
*typestring_offset *typestring_offset
@ -2708,7 +2711,7 @@ static unsigned int get_required_buffer_size_type(
case RPC_FC_SMFARRAY: case RPC_FC_SMFARRAY:
case RPC_FC_LGFARRAY: case RPC_FC_LGFARRAY:
return type->dim * get_required_buffer_size_type(type->ref, name, alignment); return type_array_get_dim(type) * get_required_buffer_size_type(type->ref, name, alignment);
default: default:
return 0; return 0;
@ -2917,11 +2920,11 @@ expr_t *get_size_is_expr(const type_t *t, const char *name)
{ {
expr_t *x = NULL; expr_t *x = NULL;
for ( ; is_ptr(t) || is_array(t); t = t->ref) for ( ; is_array(t); t = t->ref)
if (t->size_is) if (type_array_has_conformance(t))
{ {
if (!x) if (!x)
x = t->size_is; x = type_array_get_conformance(t);
else else
error("%s: multidimensional conformant" error("%s: multidimensional conformant"
" arrays not supported at the top level\n", " arrays not supported at the top level\n",
@ -2944,19 +2947,19 @@ static void write_parameter_conf_or_var_exprs(FILE *file, int indent, const char
break; break;
else if (is_array(type) || is_string_type(var->attrs, type)) else if (is_array(type) || is_string_type(var->attrs, type))
{ {
if (is_conformance_needed_for_phase(phase)) if (is_conformance_needed_for_phase(phase) && is_array(type))
{ {
if (type->size_is) if (type_array_has_conformance(type))
{ {
print_file(file, indent, "__frame->_StubMsg.MaxCount = (ULONG_PTR)"); print_file(file, indent, "__frame->_StubMsg.MaxCount = (ULONG_PTR)");
write_expr(file, type->size_is, 1, 1, NULL, NULL, local_var_prefix); write_expr(file, type_array_get_conformance(type), 1, 1, NULL, NULL, local_var_prefix);
fprintf(file, ";\n\n"); fprintf(file, ";\n\n");
} }
if (type->length_is) if (type_array_has_variance(type))
{ {
print_file(file, indent, "__frame->_StubMsg.Offset = 0;\n"); /* FIXME */ print_file(file, indent, "__frame->_StubMsg.Offset = 0;\n"); /* FIXME */
print_file(file, indent, "__frame->_StubMsg.ActualCount = (ULONG_PTR)"); print_file(file, indent, "__frame->_StubMsg.ActualCount = (ULONG_PTR)");
write_expr(file, type->length_is, 1, 1, NULL, NULL, local_var_prefix); write_expr(file, type_array_get_variance(type), 1, 1, NULL, NULL, local_var_prefix);
fprintf(file, ";\n\n"); fprintf(file, ";\n\n");
} }
} }
@ -3080,7 +3083,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
{ {
if (phase == PHASE_FREE || pass == PASS_RETURN || pointer_type == RPC_FC_UP) if (phase == PHASE_FREE || pass == PASS_RETURN || pointer_type == RPC_FC_UP)
print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var,
start_offset - (type->size_is ? 4 : 2)); start_offset - (is_conformant_array(type) ? 4 : 2));
else else
print_phase_function(file, indent, "ConformantString", local_var_prefix, print_phase_function(file, indent, "ConformantString", local_var_prefix,
phase, var, start_offset); phase, var, start_offset);
@ -3305,7 +3308,7 @@ void declare_stub_args( FILE *file, int indent, const var_t *func )
print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name); print_file(file, indent, "NDR_SCONTEXT %s;\n", var->name);
else else
{ {
if (!in_attr && !var->type->size_is && !is_string) if (!in_attr && !is_conformant_array(var->type) && !is_string)
{ {
print_file(file, indent, ""); print_file(file, indent, "");
write_type_decl(file, var->type->declarray ? var->type : var->type->ref, write_type_decl(file, var->type->declarray ? var->type : var->type->ref,
@ -3358,15 +3361,19 @@ void assign_stub_out_args( FILE *file, int indent, const var_t *func, const char
print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n",
var->type->typestring_offset); var->type->typestring_offset);
} }
else if (var->type->size_is) else if (is_array(var->type) &&
type_array_has_conformance(var->type))
{ {
unsigned int size, align = 0; unsigned int size, align = 0;
type_t *type = var->type; type_t *type = var->type;
fprintf(file, " = NdrAllocate(&__frame->_StubMsg, "); fprintf(file, " = NdrAllocate(&__frame->_StubMsg, ");
for ( ; type->size_is ; type = type->ref) for ( ;
is_array(type) && type_array_has_conformance(type);
type = type->ref)
{ {
write_expr(file, type->size_is, TRUE, TRUE, NULL, NULL, local_var_prefix); write_expr(file, type_array_get_conformance(type), TRUE,
TRUE, NULL, NULL, local_var_prefix);
fprintf(file, " * "); fprintf(file, " * ");
} }
size = type_memsize(type, &align); size = type_memsize(type, &align);

View File

@ -105,4 +105,34 @@ static inline int type_is_complete(const type_t *type)
return TRUE; return TRUE;
} }
static inline int type_array_has_conformance(const type_t *type)
{
assert(is_array(type));
return (type->details.array.size_is != NULL);
}
static inline int type_array_has_variance(const type_t *type)
{
assert(is_array(type));
return (type->details.array.length_is != NULL);
}
static inline unsigned long type_array_get_dim(const type_t *type)
{
assert(is_array(type));
return type->details.array.dim;
}
static inline expr_t *type_array_get_conformance(const type_t *type)
{
assert(is_array(type));
return type->details.array.size_is;
}
static inline expr_t *type_array_get_variance(const type_t *type)
{
assert(is_array(type));
return type->details.array.length_is;
}
#endif /* WIDL_TYPE_TREE_H */ #endif /* WIDL_TYPE_TREE_H */

View File

@ -289,6 +289,12 @@ struct module_details
func_list_t *funcs; func_list_t *funcs;
}; };
struct array_details
{
unsigned long dim;
expr_t *size_is, *length_is;
};
struct _type_t { struct _type_t {
const char *name; const char *name;
enum type_kind kind; enum type_kind kind;
@ -302,10 +308,9 @@ struct _type_t {
struct func_details *function; struct func_details *function;
struct iface_details *iface; struct iface_details *iface;
struct module_details *module; struct module_details *module;
struct array_details array;
} details; } details;
ifref_list_t *ifaces; /* coclasses */ ifref_list_t *ifaces; /* coclasses */
unsigned long dim; /* array dimension */
expr_t *size_is, *length_is;
type_t *orig; /* dup'd types */ type_t *orig; /* dup'd types */
unsigned int typestring_offset; unsigned int typestring_offset;
unsigned int ptrdesc; /* used for complex structs */ unsigned int ptrdesc; /* used for complex structs */

View File

@ -1095,10 +1095,10 @@ static int encode_var(
arraydata += 2; arraydata += 2;
for (atype = type; atype->declarray; atype = atype->ref) for (atype = type; atype->declarray; atype = atype->ref)
{ {
arraydata[0] = atype->dim; arraydata[0] = type_array_get_dim(atype);
arraydata[1] = 0; arraydata[1] = 0;
arraydata += 2; arraydata += 2;
elements *= atype->dim; elements *= type_array_get_dim(atype);
} }
typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0); typeoffset = ctl2_alloc_segment(typelib, MSFT_SEG_TYPEDESC, 8, 0);