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) ...@@ -350,6 +350,12 @@ s_sum_padded(padded_t *p)
return p->i + p->c; return p->i + p->c;
} }
int
s_sum_bogus(bogus_t *b)
{
return *b->h.p1 + *b->p2 + *b->p3 + b->c;
}
void void
s_stop(void) s_stop(void)
{ {
...@@ -399,6 +405,7 @@ basic_tests(void) ...@@ -399,6 +405,7 @@ basic_tests(void)
pints_t pints; pints_t pints;
ptypes_t ptypes; ptypes_t ptypes;
padded_t padded; padded_t padded;
bogus_t bogus;
int i1, i2, i3, *pi2, *pi3, **ppi3; int i1, i2, i3, *pi2, *pi3, **ppi3;
double u, v; double u, v;
float s, t; float s, t;
...@@ -476,6 +483,15 @@ basic_tests(void) ...@@ -476,6 +483,15 @@ basic_tests(void)
padded.i = -3; padded.i = -3;
padded.c = 8; padded.c = 8;
ok(sum_padded(&padded) == 5, "RPC sum_padded\n"); 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 static void
......
...@@ -208,5 +208,20 @@ interface IServer ...@@ -208,5 +208,20 @@ interface IServer
int sum_padded(padded_t *p); 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); void stop(void);
} }
...@@ -1249,6 +1249,7 @@ static type_t *make_type(unsigned char type, type_t *ref) ...@@ -1249,6 +1249,7 @@ static type_t *make_type(unsigned char type, type_t *ref)
t->size_is = NULL; t->size_is = NULL;
t->length_is = NULL; t->length_is = NULL;
t->typestring_offset = 0; t->typestring_offset = 0;
t->ptrdesc = 0;
t->declarray = FALSE; t->declarray = FALSE;
t->ignore = (parse_only != 0); t->ignore = (parse_only != 0);
t->is_const = FALSE; t->is_const = FALSE;
......
...@@ -100,6 +100,7 @@ const char *string_of_type(unsigned char type) ...@@ -100,6 +100,7 @@ const char *string_of_type(unsigned char type)
case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY"; case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY";
case RPC_FC_ALIGNM4: return "FC_ALIGNM4"; case RPC_FC_ALIGNM4: return "FC_ALIGNM4";
case RPC_FC_ALIGNM8: return "FC_ALIGNM8"; case RPC_FC_ALIGNM8: return "FC_ALIGNM8";
case RPC_FC_POINTER: return "FC_POINTER";
default: default:
error("string_of_type: unknown type 0x%02x\n", type); error("string_of_type: unknown type 0x%02x\n", type);
return NULL; return NULL;
...@@ -918,7 +919,8 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff) ...@@ -918,7 +919,8 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
*tfsoff += 2; *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) unsigned int *corroff, unsigned int *tfsoff)
{ {
if (is_embedded_complex(type)) if (is_embedded_complex(type))
...@@ -926,7 +928,7 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field, ...@@ -926,7 +928,7 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field,
size_t absoff; size_t absoff;
short reloff; 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; absoff = *corroff;
*corroff += 8; *corroff += 8;
...@@ -946,7 +948,10 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field, ...@@ -946,7 +948,10 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field,
} }
else if (is_ptr(type)) 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; *tfsoff += 1;
} }
else if (!write_base_type(file, type, tfsoff)) 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 ...@@ -1521,7 +1526,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
*typestring_offset += 1; *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); write_end(file, typestring_offset);
} }
else else
...@@ -1579,7 +1584,8 @@ static void write_struct_members(FILE *file, const type_t *type, ...@@ -1579,7 +1584,8 @@ static void write_struct_members(FILE *file, const type_t *type,
offset = (offset + (align - 1)) & ~(align - 1); offset = (offset + (align - 1)) & ~(align - 1);
*typestring_offset += 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; offset += size;
} }
} }
...@@ -1655,8 +1661,12 @@ static size_t write_struct_tfs(FILE *file, type_t *type, ...@@ -1655,8 +1661,12 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
if (type->type == RPC_FC_BOGUS_STRUCT) if (type->type == RPC_FC_BOGUS_STRUCT)
{ {
/* On the sizing pass, type->ptrdesc may be zero, but it's ok as
print_file(file, 2, "NdrFcShort(0x0),\t/* FIXME: pointer stuff */\n"); 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; *tfsoff += 2;
} }
else if ((type->type == RPC_FC_PSTRUCT) || else if ((type->type == RPC_FC_PSTRUCT) ||
...@@ -1673,6 +1683,20 @@ static size_t write_struct_tfs(FILE *file, type_t *type, ...@@ -1673,6 +1683,20 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
write_struct_members(file, type, &corroff, tfsoff); 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; current_structure = save_current_structure;
return start_offset; return start_offset;
} }
......
...@@ -214,6 +214,7 @@ struct _type_t { ...@@ -214,6 +214,7 @@ struct _type_t {
expr_t *size_is, *length_is; 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 */
int typelib_idx; int typelib_idx;
unsigned int declarray : 1; /* if declared as an array */ unsigned int declarray : 1; /* if declared as an array */
unsigned int ignore : 1; 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