widl: Handle pointers to conformant arrays (e.g., "[size_is(, n)] int **p; ").
This commit is contained in:
parent
8caa325eb7
commit
8d15820f79
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue