widl: Support correlation descriptors in structures.
This commit is contained in:
parent
e9c771f98b
commit
73023890c5
|
@ -43,6 +43,9 @@
|
|||
#include "typegen.h"
|
||||
|
||||
static const func_t *current_func;
|
||||
static const var_t *current_fields;
|
||||
|
||||
static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array);
|
||||
|
||||
static int print_file(FILE *file, int indent, const char *format, ...)
|
||||
{
|
||||
|
@ -215,8 +218,7 @@ void write_procformatstring(FILE *file, type_t *iface)
|
|||
}
|
||||
|
||||
/* write conformance / variance descriptor */
|
||||
/* FIXME: only works for top-level variables at the moment */
|
||||
static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const expr_t *expr)
|
||||
static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const var_t *fields, const expr_t *expr)
|
||||
{
|
||||
unsigned char operator_type = 0;
|
||||
const char *operator_string = "no operators";
|
||||
|
@ -269,80 +271,104 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const expr_
|
|||
|
||||
if (subexpr->type == EXPR_IDENTIFIER)
|
||||
{
|
||||
if (func)
|
||||
{
|
||||
size_t stack_offset;
|
||||
const var_t *var = func->args;
|
||||
unsigned char param_type = 0;
|
||||
const char *param_type_string = NULL;
|
||||
const type_t *conformance_type = NULL;
|
||||
unsigned char correlation_type;
|
||||
const type_t *correlation_variable = NULL;
|
||||
unsigned char param_type = 0;
|
||||
const char *param_type_string = NULL;
|
||||
size_t offset;
|
||||
|
||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||
for (stack_offset = 0; var; stack_offset += sizeof(void *), var = PREV_LINK(var))
|
||||
if (fields)
|
||||
{
|
||||
const var_t *var;
|
||||
|
||||
for (offset = 0, var = fields; var; var = NEXT_LINK(var))
|
||||
{
|
||||
offset -= type_memsize(var->type, var->ptr_level, var->array);
|
||||
if (!strcmp(var->name, subexpr->u.sval))
|
||||
{
|
||||
conformance_type = var->type;
|
||||
correlation_variable = var->type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!conformance_type)
|
||||
error("write_conf_or_var_desc: couldn't find variable %s\n",
|
||||
subexpr->u.sval);
|
||||
if (!correlation_variable)
|
||||
error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
|
||||
subexpr->u.sval);
|
||||
|
||||
while (type_has_ref(conformance_type))
|
||||
conformance_type = conformance_type->ref;
|
||||
|
||||
switch (conformance_type->type)
|
||||
{
|
||||
case RPC_FC_CHAR:
|
||||
case RPC_FC_SMALL:
|
||||
param_type = RPC_FC_SMALL;
|
||||
param_type_string = "FC_SMALL";
|
||||
break;
|
||||
case RPC_FC_BYTE:
|
||||
case RPC_FC_USMALL:
|
||||
param_type = RPC_FC_USMALL;
|
||||
param_type_string = "FC_USMALL";
|
||||
break;
|
||||
case RPC_FC_WCHAR:
|
||||
case RPC_FC_SHORT:
|
||||
param_type = RPC_FC_SHORT;
|
||||
param_type_string = "FC_SHORT";
|
||||
break;
|
||||
case RPC_FC_USHORT:
|
||||
param_type = RPC_FC_USHORT;
|
||||
param_type_string = "FC_USHORT";
|
||||
break;
|
||||
case RPC_FC_LONG:
|
||||
param_type = RPC_FC_LONG;
|
||||
param_type_string = "FC_LONG";
|
||||
break;
|
||||
case RPC_FC_ULONG:
|
||||
param_type = RPC_FC_ULONG;
|
||||
param_type_string = "FC_ULONG";
|
||||
break;
|
||||
default:
|
||||
error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
|
||||
conformance_type->type);
|
||||
}
|
||||
|
||||
print_file(file, 2, "0x%x, /* Corr desc: parameter, %s */\n",
|
||||
RPC_FC_TOP_LEVEL_CONFORMANCE | param_type,
|
||||
param_type_string);
|
||||
print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string);
|
||||
print_file(file, 2, "0x%x, /* x86 stack size / offset = %d */\n", stack_offset, stack_offset);
|
||||
correlation_type = RPC_FC_NORMAL_CONFORMANCE;
|
||||
}
|
||||
else
|
||||
error("write_conf_or_var_desc: not supported for non-functions yet\n");
|
||||
{
|
||||
const var_t *var = func->args;
|
||||
|
||||
while (NEXT_LINK(var)) var = NEXT_LINK(var);
|
||||
/* FIXME: not all stack variables are sizeof(void *) */
|
||||
for (offset = 0; var; offset += sizeof(void *), var = PREV_LINK(var))
|
||||
{
|
||||
if (!strcmp(var->name, subexpr->u.sval))
|
||||
{
|
||||
correlation_variable = var->type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!correlation_variable)
|
||||
error("write_conf_or_var_desc: couldn't find variable %s in function\n",
|
||||
subexpr->u.sval);
|
||||
|
||||
correlation_type = RPC_FC_TOP_LEVEL_CONFORMANCE;
|
||||
}
|
||||
|
||||
while (type_has_ref(correlation_variable))
|
||||
correlation_variable = correlation_variable->ref;
|
||||
|
||||
switch (correlation_variable->type)
|
||||
{
|
||||
case RPC_FC_CHAR:
|
||||
case RPC_FC_SMALL:
|
||||
param_type = RPC_FC_SMALL;
|
||||
param_type_string = "FC_SMALL";
|
||||
break;
|
||||
case RPC_FC_BYTE:
|
||||
case RPC_FC_USMALL:
|
||||
param_type = RPC_FC_USMALL;
|
||||
param_type_string = "FC_USMALL";
|
||||
break;
|
||||
case RPC_FC_WCHAR:
|
||||
case RPC_FC_SHORT:
|
||||
param_type = RPC_FC_SHORT;
|
||||
param_type_string = "FC_SHORT";
|
||||
break;
|
||||
case RPC_FC_USHORT:
|
||||
param_type = RPC_FC_USHORT;
|
||||
param_type_string = "FC_USHORT";
|
||||
break;
|
||||
case RPC_FC_LONG:
|
||||
param_type = RPC_FC_LONG;
|
||||
param_type_string = "FC_LONG";
|
||||
break;
|
||||
case RPC_FC_ULONG:
|
||||
param_type = RPC_FC_ULONG;
|
||||
param_type_string = "FC_ULONG";
|
||||
break;
|
||||
default:
|
||||
error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
|
||||
correlation_variable->type);
|
||||
}
|
||||
|
||||
print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n",
|
||||
correlation_type | param_type,
|
||||
correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "parameter, " : "",
|
||||
param_type_string);
|
||||
print_file(file, 2, "0x%x, /* %s */\n", operator_type, operator_string);
|
||||
print_file(file, 2, "0x%x, /* %soffset = %d */\n",
|
||||
offset,
|
||||
correlation_type == RPC_FC_TOP_LEVEL_CONFORMANCE ? "x86 stack size / " : "",
|
||||
offset);
|
||||
}
|
||||
else
|
||||
error("write_conf_or_var_desc: expression type %d\n", subexpr->type);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static size_t type_memsize(const type_t *t, int ptr_level, const expr_t *array);
|
||||
|
||||
static size_t fields_memsize(const var_t *v)
|
||||
{
|
||||
size_t size = 0;
|
||||
|
@ -454,7 +480,7 @@ static size_t write_string_tfs(FILE *file, const attr_t *attrs,
|
|||
print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED);
|
||||
typestring_size = 2;
|
||||
|
||||
typestring_size += write_conf_or_var_desc(file, current_func, size_is);
|
||||
typestring_size += write_conf_or_var_desc(file, current_func, NULL, size_is);
|
||||
|
||||
return typestring_size;
|
||||
}
|
||||
|
@ -557,7 +583,9 @@ static size_t write_array_tfs(FILE *file, const attr_t *attrs,
|
|||
print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
|
||||
typestring_size += 2;
|
||||
|
||||
typestring_size += write_conf_or_var_desc(file, current_func, length_is);
|
||||
typestring_size += write_conf_or_var_desc(file, current_func,
|
||||
current_fields,
|
||||
length_is);
|
||||
|
||||
/* FIXME: write out pointer descriptor if necessary */
|
||||
|
||||
|
@ -580,7 +608,8 @@ static size_t write_array_tfs(FILE *file, const attr_t *attrs,
|
|||
print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
|
||||
typestring_size = 4;
|
||||
|
||||
typestring_size += write_conf_or_var_desc(file, current_func, size_is);
|
||||
typestring_size += write_conf_or_var_desc(file, current_func,
|
||||
current_fields, size_is);
|
||||
|
||||
/* FIXME: write out pointer descriptor if necessary */
|
||||
|
||||
|
@ -603,8 +632,11 @@ static size_t write_array_tfs(FILE *file, const attr_t *attrs,
|
|||
print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", element_size, element_size);
|
||||
typestring_size = 4;
|
||||
|
||||
typestring_size += write_conf_or_var_desc(file, current_func, size_is);
|
||||
typestring_size += write_conf_or_var_desc(file, current_func, length_is);
|
||||
typestring_size += write_conf_or_var_desc(file, current_func,
|
||||
current_fields, size_is);
|
||||
typestring_size += write_conf_or_var_desc(file, current_func,
|
||||
current_fields,
|
||||
length_is);
|
||||
|
||||
/* FIXME: write out pointer descriptor if necessary */
|
||||
|
||||
|
|
Loading…
Reference in New Issue