widl: Handle pointers to conformant arrays (e.g., "[size_is(, n)] int **p; ").

This commit is contained in:
Dan Hipschman 2007-11-02 15:24:08 -07:00 committed by Alexandre Julliard
parent 8caa325eb7
commit 8d15820f79
4 changed files with 50 additions and 2 deletions

View File

@ -481,6 +481,12 @@ s_get_name(name_t *name)
name->name[name->size - 1] = 0;
}
int
s_sum_pcarr2(int n, int **pa)
{
return s_sum_conf_array(*pa, n);
}
void
s_stop(void)
{
@ -812,6 +818,7 @@ pointer_tests(void)
bstr_t bstr = &bstr_data[1];
name_t name;
void *buffer;
int *pa2;
ok(test_list_length(list) == 3, "RPC test_list_length\n");
ok(square_puint(p1) == 121, "RPC square_puint\n");
@ -862,6 +869,9 @@ pointer_tests(void)
todo_wine
ok(name.name == buffer, "[in,out] pointer should have stayed as %p but instead changed to %p\n", name.name, buffer);
HeapFree(GetProcessHeap(), 0, name.name);
pa2 = a;
ok(sum_pcarr2(4, &pa2) == 10, "RPC sum_pcarr2\n");
}
static int

View File

@ -297,5 +297,7 @@ cpp_quote("#endif")
} name_t;
void get_name([in,out] name_t *name);
int sum_pcarr2(int n, [size_is(, n)] int **pa);
void stop(void);
}

View File

@ -29,6 +29,7 @@ extern void *get_attrp(const attr_list_t *list, enum attr_type t);
extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t);
extern int is_void(const type_t *t);
extern int is_conformant_array(const type_t *t);
extern int is_declptr(const type_t *t);
extern void write_name(FILE *h, const var_t *v);
extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v);
extern const char* get_name(const var_t *v);
@ -67,7 +68,7 @@ extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
static inline int last_ptr(const type_t *type)
{
return is_ptr(type) && !is_ptr(type->ref);
return is_ptr(type) && !is_declptr(type->ref);
}
static inline int last_array(const type_t *type)

View File

@ -1420,7 +1420,7 @@ static void write_pointer_description(FILE *file, type_t *type,
&offset_in_memory, &offset_in_buffer, typestring_offset);
}
static int is_declptr(const type_t *t)
int is_declptr(const type_t *t)
{
return is_ptr(t) || (is_conformant_array(t) && !t->declarray);
}
@ -2083,6 +2083,14 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
size_t off;
off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset);
ptr_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
/* Top level pointers to conformant arrays may be handled specially
since we can bypass the pointer, but if the array is burried
beneath another pointer (e.g., "[size_is(,n)] int **p" then we
always need to write the pointer. */
if (!ptr_type && var->type != type)
/* FIXME: This should use pointer_default, but the information
isn't kept around for arrays. */
ptr_type = RPC_FC_UP;
if (ptr_type && ptr_type != RPC_FC_RP)
{
unsigned int absoff = type->typestring_offset;
@ -2711,6 +2719,13 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
{
unsigned char tc = type->type;
const char *array_type = "FixedArray";
type_t *st;
for (st = type->ref; is_ptr(st) || is_array(st); st = st->ref)
if (st->size_is)
error("in function %s: multidimensional conformant arrays"
" not supported at the top level\n",
func->def->name);
if (tc == RPC_FC_SMVARRAY || tc == RPC_FC_LGVARRAY)
{
@ -2826,8 +2841,28 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
else
{
const var_t *iid;
expr_t *sx = NULL;
type_t *st;
for (st = type->ref; is_ptr(st) || is_array(st); st = st->ref)
if (st->size_is)
{
if (!sx)
sx = st->size_is;
else
error("in function %s: multidimensional conformant"
" arrays not supported at the top level\n",
func->def->name);
}
if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name );
else if (sx)
{
print_file(file, indent, "_StubMsg.MaxCount = (unsigned long) ");
write_expr(file, sx, 1);
fprintf(file, ";\n\n");
}
if (var->type->ref->type == RPC_FC_IP)
print_phase_function(file, indent, "InterfacePointer", phase, var, start_offset);
else