Dan Hipschman : widl: Handle embedded interface pointers.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jun 15 07:23:03 CDT 2007
Module: wine
Branch: master
Commit: 8709a06028709b11ade91087c1bdba8678adc65c
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8709a06028709b11ade91087c1bdba8678adc65c
Author: Dan Hipschman <dsh at linux.ucla.edu>
Date: Thu Jun 14 18:27:19 2007 -0700
widl: Handle embedded interface pointers.
---
tools/widl/parser.y | 15 ++++++++++++++-
tools/widl/typegen.c | 43 ++++++++++++++++++++++++++-----------------
2 files changed, 40 insertions(+), 18 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index a991cad..739b60c 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -1668,8 +1668,21 @@ static int get_struct_type(var_list_t *fields)
{
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;
continue;
}
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 6f12a22..9a5910a 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -195,7 +195,8 @@ static int is_user_type(const type_t *t)
static int is_embedded_complex(const type_t *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)
@@ -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,
unsigned int *corroff, unsigned int *tfsoff)
{
- if (is_ptr(type))
- {
- print_file(file, 2, "0x8,\t/* FC_LONG */\n");
- *tfsoff += 1;
- }
- else if (is_embedded_complex(type))
+ if (is_embedded_complex(type))
{
size_t absoff;
short reloff;
@@ -907,6 +903,11 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field,
reloff, reloff, absoff);
*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))
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;
}
-static size_t write_ip_tfs(FILE *file, const func_t *func, const type_t *type, const var_t *var,
- unsigned int *typeformat_offset)
+static size_t write_ip_tfs(FILE *file, const func_t *func, const attr_list_t *attrs,
+ type_t *type, unsigned int *typeformat_offset)
{
size_t i;
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)
{
@@ -1442,6 +1443,8 @@ static size_t write_ip_tfs(FILE *file, const func_t *func, const type_t *type, c
if (! uuid)
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, "0x5a,\t/* FC_CONSTANT_IID */\n");
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)
{
- 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 */
@@ -1609,14 +1612,20 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
{
type_t *ref = type->ref;
- if (!processed(ref) && !is_base_type(ref->type))
- retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff);
+ if (ref->type == RPC_FC_IP)
+ {
+ write_ip_tfs(file, NULL, attrs, type, tfsoff);
+ }
+ else
+ {
+ if (!processed(ref) && !is_base_type(ref->type))
+ retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff);
- /* top-level pointers are handled inline for structures */
- if (write_ptr)
- write_pointer_tfs(file, type, tfsoff);
+ if (write_ptr)
+ write_pointer_tfs(file, type, tfsoff);
- retmask |= 1;
+ retmask |= 1;
+ }
}
else if (type->declarray && is_conformant_array(type))
; /* conformant arrays and strings are handled specially */
More information about the wine-cvs
mailing list