widl: Handle embedded interface pointers.
This commit is contained in:
parent
e41adf76be
commit
8709a06028
|
@ -1668,8 +1668,21 @@ static int get_struct_type(var_list_t *fields)
|
||||||
{
|
{
|
||||||
type_t *t = field->type;
|
type_t *t = field->type;
|
||||||
|
|
||||||
if (is_ptr(field->type))
|
if (is_ptr(t))
|
||||||
{
|
{
|
||||||
|
do
|
||||||
|
t = t->ref;
|
||||||
|
while (is_ptr(t));
|
||||||
|
|
||||||
|
switch (t->type)
|
||||||
|
{
|
||||||
|
case RPC_FC_IP:
|
||||||
|
case RPC_FC_ENCAPSULATED_UNION:
|
||||||
|
case RPC_FC_NON_ENCAPSULATED_UNION:
|
||||||
|
case RPC_FC_BOGUS_STRUCT:
|
||||||
|
return RPC_FC_BOGUS_STRUCT;
|
||||||
|
}
|
||||||
|
|
||||||
has_pointer = 1;
|
has_pointer = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,7 +195,8 @@ static int is_user_type(const type_t *t)
|
||||||
static int is_embedded_complex(const type_t *type)
|
static int is_embedded_complex(const type_t *type)
|
||||||
{
|
{
|
||||||
unsigned char tc = type->type;
|
unsigned char tc = type->type;
|
||||||
return is_struct(tc) || is_union(tc) || is_array(type) || is_user_type(type);
|
return is_struct(tc) || is_union(tc) || is_array(type) || is_user_type(type)
|
||||||
|
|| (is_ptr(type) && type->ref->type == RPC_FC_IP);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compare_expr(const expr_t *a, const expr_t *b)
|
static int compare_expr(const expr_t *a, const expr_t *b)
|
||||||
|
@ -879,12 +880,7 @@ static void write_user_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
|
||||||
static void write_member_type(FILE *file, type_t *type, const var_t *field,
|
static void write_member_type(FILE *file, type_t *type, const var_t *field,
|
||||||
unsigned int *corroff, unsigned int *tfsoff)
|
unsigned int *corroff, unsigned int *tfsoff)
|
||||||
{
|
{
|
||||||
if (is_ptr(type))
|
if (is_embedded_complex(type))
|
||||||
{
|
|
||||||
print_file(file, 2, "0x8,\t/* FC_LONG */\n");
|
|
||||||
*tfsoff += 1;
|
|
||||||
}
|
|
||||||
else if (is_embedded_complex(type))
|
|
||||||
{
|
{
|
||||||
size_t absoff;
|
size_t absoff;
|
||||||
short reloff;
|
short reloff;
|
||||||
|
@ -907,6 +903,11 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field,
|
||||||
reloff, reloff, absoff);
|
reloff, reloff, absoff);
|
||||||
*tfsoff += 4;
|
*tfsoff += 4;
|
||||||
}
|
}
|
||||||
|
else if (is_ptr(type))
|
||||||
|
{
|
||||||
|
print_file(file, 2, "0x8,\t/* FC_LONG */\n");
|
||||||
|
*tfsoff += 1;
|
||||||
|
}
|
||||||
else if (!write_base_type(file, type, tfsoff))
|
else if (!write_base_type(file, type, tfsoff))
|
||||||
error("Unsupported member type 0x%x\n", type->type);
|
error("Unsupported member type 0x%x\n", type->type);
|
||||||
}
|
}
|
||||||
|
@ -1415,12 +1416,12 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
|
||||||
return start_offset;
|
return start_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t write_ip_tfs(FILE *file, const func_t *func, const type_t *type, const var_t *var,
|
static size_t write_ip_tfs(FILE *file, const func_t *func, const attr_list_t *attrs,
|
||||||
unsigned int *typeformat_offset)
|
type_t *type, unsigned int *typeformat_offset)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t start_offset = *typeformat_offset;
|
size_t start_offset = *typeformat_offset;
|
||||||
const var_t *iid = get_attrp(var->attrs, ATTR_IIDIS);
|
const var_t *iid = get_attrp(attrs, ATTR_IIDIS);
|
||||||
|
|
||||||
if (iid)
|
if (iid)
|
||||||
{
|
{
|
||||||
|
@ -1442,6 +1443,8 @@ static size_t write_ip_tfs(FILE *file, const func_t *func, const type_t *type, c
|
||||||
if (! uuid)
|
if (! uuid)
|
||||||
error("%s: interface %s missing UUID\n", __FUNCTION__, base->name);
|
error("%s: interface %s missing UUID\n", __FUNCTION__, base->name);
|
||||||
|
|
||||||
|
update_tfsoff(type, start_offset, file);
|
||||||
|
print_file(file, 0, "/* %d */\n", start_offset);
|
||||||
print_file(file, 2, "0x2f,\t/* FC_IP */\n");
|
print_file(file, 2, "0x2f,\t/* FC_IP */\n");
|
||||||
print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n");
|
print_file(file, 2, "0x5a,\t/* FC_CONSTANT_IID */\n");
|
||||||
print_file(file, 2, "NdrFcLong(0x%08lx),\n", uuid->Data1);
|
print_file(file, 2, "NdrFcLong(0x%08lx),\n", uuid->Data1);
|
||||||
|
@ -1539,7 +1542,7 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
|
||||||
|
|
||||||
if (base->type == RPC_FC_IP)
|
if (base->type == RPC_FC_IP)
|
||||||
{
|
{
|
||||||
return write_ip_tfs(file, func, type, var, typeformat_offset);
|
return write_ip_tfs(file, func, var->attrs, type, typeformat_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* special case for pointers to base types */
|
/* special case for pointers to base types */
|
||||||
|
@ -1609,15 +1612,21 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
|
||||||
{
|
{
|
||||||
type_t *ref = type->ref;
|
type_t *ref = type->ref;
|
||||||
|
|
||||||
|
if (ref->type == RPC_FC_IP)
|
||||||
|
{
|
||||||
|
write_ip_tfs(file, NULL, attrs, type, tfsoff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (!processed(ref) && !is_base_type(ref->type))
|
if (!processed(ref) && !is_base_type(ref->type))
|
||||||
retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff);
|
retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff);
|
||||||
|
|
||||||
/* top-level pointers are handled inline for structures */
|
|
||||||
if (write_ptr)
|
if (write_ptr)
|
||||||
write_pointer_tfs(file, type, tfsoff);
|
write_pointer_tfs(file, type, tfsoff);
|
||||||
|
|
||||||
retmask |= 1;
|
retmask |= 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (type->declarray && is_conformant_array(type))
|
else if (type->declarray && is_conformant_array(type))
|
||||||
; /* conformant arrays and strings are handled specially */
|
; /* conformant arrays and strings are handled specially */
|
||||||
else if (is_array(type))
|
else if (is_array(type))
|
||||||
|
|
Loading…
Reference in New Issue