Commit 8df79f0c authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

widl: Implement pointer descriptions for complex structures.

parent b16de394
......@@ -350,6 +350,12 @@ s_sum_padded(padded_t *p)
return p->i + p->c;
}
int
s_sum_bogus(bogus_t *b)
{
return *b->h.p1 + *b->p2 + *b->p3 + b->c;
}
void
s_stop(void)
{
......@@ -399,6 +405,7 @@ basic_tests(void)
pints_t pints;
ptypes_t ptypes;
padded_t padded;
bogus_t bogus;
int i1, i2, i3, *pi2, *pi3, **ppi3;
double u, v;
float s, t;
......@@ -476,6 +483,15 @@ basic_tests(void)
padded.i = -3;
padded.c = 8;
ok(sum_padded(&padded) == 5, "RPC sum_padded\n");
i1 = 14;
i2 = -7;
i3 = -4;
bogus.h.p1 = &i1;
bogus.p2 = &i2;
bogus.p3 = &i3;
bogus.c = 9;
ok(sum_bogus(&bogus) == 12, "RPC sum_bogus\n");
}
static void
......
......@@ -208,5 +208,20 @@ interface IServer
int sum_padded(padded_t *p);
typedef struct
{
int *p1;
} bogus_helper_t;
typedef struct
{
bogus_helper_t h;
int *p2;
int *p3;
char c;
} bogus_t;
int sum_bogus(bogus_t *b);
void stop(void);
}
......@@ -1249,6 +1249,7 @@ static type_t *make_type(unsigned char type, type_t *ref)
t->size_is = NULL;
t->length_is = NULL;
t->typestring_offset = 0;
t->ptrdesc = 0;
t->declarray = FALSE;
t->ignore = (parse_only != 0);
t->is_const = FALSE;
......
......@@ -100,6 +100,7 @@ const char *string_of_type(unsigned char type)
case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY";
case RPC_FC_ALIGNM4: return "FC_ALIGNM4";
case RPC_FC_ALIGNM8: return "FC_ALIGNM8";
case RPC_FC_POINTER: return "FC_POINTER";
default:
error("string_of_type: unknown type 0x%02x\n", type);
return NULL;
......@@ -918,7 +919,8 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
*tfsoff += 2;
}
static void write_member_type(FILE *file, type_t *type, const var_t *field,
static void write_member_type(FILE *file, const type_t *cont,
const attr_list_t *attrs, const type_t *type,
unsigned int *corroff, unsigned int *tfsoff)
{
if (is_embedded_complex(type))
......@@ -926,7 +928,7 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field,
size_t absoff;
short reloff;
if (is_union(type->type) && is_attr(field->attrs, ATTR_SWITCHIS))
if (is_union(type->type) && is_attr(attrs, ATTR_SWITCHIS))
{
absoff = *corroff;
*corroff += 8;
......@@ -946,7 +948,10 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field,
}
else if (is_ptr(type))
{
print_file(file, 2, "0x8,\t/* FC_LONG */\n");
unsigned char fc = (cont->type == RPC_FC_BOGUS_STRUCT
? RPC_FC_POINTER
: RPC_FC_LONG);
print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
*tfsoff += 1;
}
else if (!write_base_type(file, type, tfsoff))
......@@ -1521,7 +1526,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
*typestring_offset += 1;
}
write_member_type(file, type->ref, NULL, NULL, typestring_offset);
write_member_type(file, type, NULL, type->ref, NULL, typestring_offset);
write_end(file, typestring_offset);
}
else
......@@ -1579,7 +1584,8 @@ static void write_struct_members(FILE *file, const type_t *type,
offset = (offset + (align - 1)) & ~(align - 1);
*typestring_offset += 1;
}
write_member_type(file, ft, field, corroff, typestring_offset);
write_member_type(file, type, field->attrs, field->type, corroff,
typestring_offset);
offset += size;
}
}
......@@ -1655,8 +1661,12 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
if (type->type == RPC_FC_BOGUS_STRUCT)
{
print_file(file, 2, "NdrFcShort(0x0),\t/* FIXME: pointer stuff */\n");
/* On the sizing pass, type->ptrdesc may be zero, but it's ok as
nothing is written to file yet. On the actual writing pass,
this will have been updated. */
short reloff = type->ptrdesc - *tfsoff;
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
reloff, reloff, type->ptrdesc);
*tfsoff += 2;
}
else if ((type->type == RPC_FC_PSTRUCT) ||
......@@ -1673,6 +1683,20 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
write_struct_members(file, type, &corroff, tfsoff);
if (type->type == RPC_FC_BOGUS_STRUCT)
{
const var_list_t *fs = type->fields;
const var_t *f;
type->ptrdesc = *tfsoff;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, const var_t, entry)
{
type_t *ft = f->type;
if (is_ptr(ft))
write_pointer_tfs(file, ft, tfsoff);
}
}
current_structure = save_current_structure;
return start_offset;
}
......
......@@ -214,6 +214,7 @@ struct _type_t {
expr_t *size_is, *length_is;
type_t *orig; /* dup'd types */
unsigned int typestring_offset;
unsigned int ptrdesc; /* used for complex structs */
int typelib_idx;
unsigned int declarray : 1; /* if declared as an array */
unsigned int ignore : 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment