widl: Add support for top-level conformances.
This commit is contained in:
parent
d8059aee3a
commit
c2406be6d4
|
@ -47,14 +47,17 @@
|
||||||
#define ROUNDING(size, alignment) (((alignment) - 1) - (((size) + ((alignment) - 1)) & ((alignment) - 1)))
|
#define ROUNDING(size, alignment) (((alignment) - 1) - (((size) + ((alignment) - 1)) & ((alignment) - 1)))
|
||||||
|
|
||||||
static const type_t *current_structure;
|
static const type_t *current_structure;
|
||||||
|
static const var_t *current_func;
|
||||||
static const type_t *current_iface;
|
static const type_t *current_iface;
|
||||||
|
|
||||||
static struct list expr_eval_routines = LIST_INIT(expr_eval_routines);
|
static struct list expr_eval_routines = LIST_INIT(expr_eval_routines);
|
||||||
struct expr_eval_routine
|
struct expr_eval_routine
|
||||||
{
|
{
|
||||||
struct list entry;
|
struct list entry;
|
||||||
const type_t *structure;
|
const type_t *iface;
|
||||||
unsigned int baseoff;
|
const type_t *cont_type;
|
||||||
|
char *name;
|
||||||
|
unsigned int baseoff;
|
||||||
const expr_t *expr;
|
const expr_t *expr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1031,14 +1034,16 @@ static int write_base_type(FILE *file, const type_t *type, int convert_to_signed
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write conformance / variance descriptor */
|
/* write conformance / variance descriptor */
|
||||||
static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure,
|
static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
|
||||||
unsigned int baseoff, const type_t *type,
|
unsigned int baseoff, const type_t *type,
|
||||||
const expr_t *expr)
|
const expr_t *expr)
|
||||||
{
|
{
|
||||||
unsigned char operator_type = 0;
|
unsigned char operator_type = 0;
|
||||||
unsigned char conftype = RPC_FC_NORMAL_CONFORMANCE;
|
unsigned char conftype = RPC_FC_NORMAL_CONFORMANCE;
|
||||||
const char *conftype_string = "";
|
const char *conftype_string = "field";
|
||||||
const expr_t *subexpr;
|
const expr_t *subexpr;
|
||||||
|
const type_t *iface = NULL;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
if (!expr)
|
if (!expr)
|
||||||
{
|
{
|
||||||
|
@ -1061,20 +1066,22 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure,
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!structure)
|
if (!cont_type) /* top-level conformance */
|
||||||
{
|
{
|
||||||
/* Top-level conformance calculations are done inline. */
|
conftype = RPC_FC_TOP_LEVEL_CONFORMANCE;
|
||||||
print_file (file, 2, "0x%x,\t/* Corr desc: parameter */\n",
|
conftype_string = "parameter";
|
||||||
RPC_FC_TOP_LEVEL_CONFORMANCE);
|
cont_type = current_func->type;
|
||||||
print_file (file, 2, "0x0,\n");
|
name = current_func->name;
|
||||||
print_file (file, 2, "NdrFcShort(0x0),\n");
|
iface = current_iface;
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (is_ptr(type) || (is_array(type) && type_array_is_decl_as_ptr(type)))
|
|
||||||
{
|
{
|
||||||
conftype = RPC_FC_POINTER_CONFORMANCE;
|
name = cont_type->name;
|
||||||
conftype_string = "field pointer, ";
|
if (is_ptr(type) || (is_array(type) && type_array_is_decl_as_ptr(type)))
|
||||||
|
{
|
||||||
|
conftype = RPC_FC_POINTER_CONFORMANCE;
|
||||||
|
conftype_string = "field pointer";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subexpr = expr;
|
subexpr = expr;
|
||||||
|
@ -1122,23 +1129,45 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure,
|
||||||
unsigned char param_type = 0;
|
unsigned char param_type = 0;
|
||||||
unsigned int offset = 0;
|
unsigned int offset = 0;
|
||||||
const var_t *var;
|
const var_t *var;
|
||||||
var_list_t *fields = type_struct_get_fields(structure);
|
struct expr_loc expr_loc;
|
||||||
|
|
||||||
if (fields) LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
|
if (type_get_type(cont_type) == TYPE_FUNCTION)
|
||||||
{
|
{
|
||||||
unsigned int size = field_memsize( var->type, &offset );
|
var_list_t *args = type_get_function_args( cont_type );
|
||||||
if (var->name && !strcmp(var->name, subexpr->u.sval))
|
|
||||||
{
|
|
||||||
correlation_variable = var->type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
offset += size;
|
|
||||||
}
|
|
||||||
if (!correlation_variable)
|
|
||||||
error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
|
|
||||||
subexpr->u.sval);
|
|
||||||
|
|
||||||
correlation_variable = expr_resolve_type(NULL, structure, expr);
|
if (is_object( iface )) offset += pointer_size;
|
||||||
|
if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
|
||||||
|
{
|
||||||
|
if (var->name && !strcmp(var->name, subexpr->u.sval))
|
||||||
|
{
|
||||||
|
expr_loc.v = var;
|
||||||
|
correlation_variable = var->type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += get_stack_size( var->type, var->attrs, NULL );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var_list_t *fields = type_struct_get_fields( cont_type );
|
||||||
|
|
||||||
|
if (fields) LIST_FOR_EACH_ENTRY( var, fields, const var_t, entry )
|
||||||
|
{
|
||||||
|
unsigned int size = field_memsize( var->type, &offset );
|
||||||
|
if (var->name && !strcmp(var->name, subexpr->u.sval))
|
||||||
|
{
|
||||||
|
expr_loc.v = var;
|
||||||
|
correlation_variable = var->type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!correlation_variable)
|
||||||
|
error("write_conf_or_var_desc: couldn't find variable %s in %s\n", subexpr->u.sval, name);
|
||||||
|
expr_loc.attr = NULL;
|
||||||
|
correlation_variable = expr_resolve_type(&expr_loc, cont_type, expr);
|
||||||
|
|
||||||
offset -= baseoff;
|
offset -= baseoff;
|
||||||
|
|
||||||
|
@ -1193,9 +1222,9 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_file(file, 2, "0x%x, /* Corr desc: %s%s */\n",
|
print_file(file, 2, "0x%x,\t/* Corr desc: %s %s, %s */\n",
|
||||||
conftype | param_type, conftype_string, string_of_type(param_type));
|
conftype | param_type, conftype_string, subexpr->u.sval, string_of_type(param_type));
|
||||||
print_file(file, 2, "0x%x, /* %s */\n", operator_type,
|
print_file(file, 2, "0x%x,\t/* %s */\n", operator_type,
|
||||||
operator_type ? string_of_type(operator_type) : "no operators");
|
operator_type ? string_of_type(operator_type) : "no operators");
|
||||||
print_file(file, 2, "NdrFcShort(0x%hx),\t/* offset = %d */\n",
|
print_file(file, 2, "NdrFcShort(0x%hx),\t/* offset = %d */\n",
|
||||||
(unsigned short)offset, offset);
|
(unsigned short)offset, offset);
|
||||||
|
@ -1208,9 +1237,10 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure,
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
|
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
|
||||||
{
|
{
|
||||||
if (eval->structure == structure ||
|
if (eval->cont_type == cont_type ||
|
||||||
(eval->structure->name && structure->name &&
|
(type_get_type( eval->cont_type ) == type_get_type( cont_type ) &&
|
||||||
!strcmp(eval->structure->name, structure->name) &&
|
eval->iface == iface &&
|
||||||
|
eval->name && name && !strcmp(eval->name, name) &&
|
||||||
!compare_expr(eval->expr, expr)))
|
!compare_expr(eval->expr, expr)))
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
|
@ -1222,7 +1252,9 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure,
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
eval = xmalloc (sizeof(*eval));
|
eval = xmalloc (sizeof(*eval));
|
||||||
eval->structure = structure;
|
eval->iface = iface;
|
||||||
|
eval->cont_type = cont_type;
|
||||||
|
eval->name = xstrdup( name );
|
||||||
eval->baseoff = baseoff;
|
eval->baseoff = baseoff;
|
||||||
eval->expr = expr;
|
eval->expr = expr;
|
||||||
list_add_tail (&expr_eval_routines, &eval->entry);
|
list_add_tail (&expr_eval_routines, &eval->entry);
|
||||||
|
@ -1231,8 +1263,8 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *structure,
|
||||||
if (callback_offset > USHRT_MAX)
|
if (callback_offset > USHRT_MAX)
|
||||||
error("Maximum number of callback routines reached\n");
|
error("Maximum number of callback routines reached\n");
|
||||||
|
|
||||||
print_file(file, 2, "0x%x, /* Corr desc: %s */\n", conftype, conftype_string);
|
print_file(file, 2, "0x%x,\t/* Corr desc: %s in %s */\n", conftype, conftype_string, name);
|
||||||
print_file(file, 2, "0x%x, /* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK");
|
print_file(file, 2, "0x%x,\t/* %s */\n", RPC_FC_CALLBACK, "FC_CALLBACK");
|
||||||
print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)callback_offset, callback_offset);
|
print_file(file, 2, "NdrFcShort(0x%hx),\t/* %u */\n", (unsigned short)callback_offset, callback_offset);
|
||||||
}
|
}
|
||||||
return 4;
|
return 4;
|
||||||
|
@ -1327,6 +1359,7 @@ static unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *al
|
||||||
break;
|
break;
|
||||||
case RPC_FC_INT3264:
|
case RPC_FC_INT3264:
|
||||||
case RPC_FC_UINT3264:
|
case RPC_FC_UINT3264:
|
||||||
|
case RPC_FC_BIND_PRIMITIVE:
|
||||||
assert( pointer_size );
|
assert( pointer_size );
|
||||||
size = pointer_size;
|
size = pointer_size;
|
||||||
if (size > *align) *align = size;
|
if (size > *align) *align = size;
|
||||||
|
@ -2685,7 +2718,8 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
|
||||||
*tfsoff += 2;
|
*tfsoff += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
|
static unsigned int write_union_tfs(FILE *file, const attr_list_t *attrs,
|
||||||
|
type_t *type, unsigned int *tfsoff)
|
||||||
{
|
{
|
||||||
unsigned int start_offset;
|
unsigned int start_offset;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
@ -2755,7 +2789,7 @@ static unsigned int write_union_tfs(FILE *file, type_t *type, unsigned int *tfso
|
||||||
}
|
}
|
||||||
else if (is_attr(type->attrs, ATTR_SWITCHTYPE))
|
else if (is_attr(type->attrs, ATTR_SWITCHTYPE))
|
||||||
{
|
{
|
||||||
static const expr_t dummy_expr; /* FIXME */
|
const expr_t *switch_is = get_attrp(attrs, ATTR_SWITCHIS);
|
||||||
const type_t *st = get_attrp(type->attrs, ATTR_SWITCHTYPE);
|
const type_t *st = get_attrp(type->attrs, ATTR_SWITCHTYPE);
|
||||||
unsigned char fc;
|
unsigned char fc;
|
||||||
|
|
||||||
|
@ -2788,8 +2822,7 @@ static unsigned int write_union_tfs(FILE *file, type_t *type, unsigned int *tfso
|
||||||
print_file(file, 2, "0x%x,\t/* Switch type= %s */\n",
|
print_file(file, 2, "0x%x,\t/* Switch type= %s */\n",
|
||||||
fc, string_of_type(fc));
|
fc, string_of_type(fc));
|
||||||
*tfsoff += 2;
|
*tfsoff += 2;
|
||||||
|
*tfsoff += write_conf_or_var_desc(file, current_structure, 0, st, switch_is );
|
||||||
*tfsoff += write_conf_or_var_desc(file, NULL, *tfsoff, st, &dummy_expr );
|
|
||||||
print_file(file, 2, "NdrFcShort(0x2),\t/* Offset= 2 (%u) */\n", *tfsoff + 2);
|
print_file(file, 2, "NdrFcShort(0x2),\t/* Offset= 2 (%u) */\n", *tfsoff + 2);
|
||||||
*tfsoff += 2;
|
*tfsoff += 2;
|
||||||
print_file(file, 0, "/* %u */\n", *tfsoff);
|
print_file(file, 0, "/* %u */\n", *tfsoff);
|
||||||
|
@ -3014,7 +3047,7 @@ static unsigned int write_type_tfs(FILE *file, int indent,
|
||||||
case TGT_STRUCT:
|
case TGT_STRUCT:
|
||||||
return write_struct_tfs(file, type, name, typeformat_offset);
|
return write_struct_tfs(file, type, name, typeformat_offset);
|
||||||
case TGT_UNION:
|
case TGT_UNION:
|
||||||
return write_union_tfs(file, type, typeformat_offset);
|
return write_union_tfs(file, attrs, type, typeformat_offset);
|
||||||
case TGT_ENUM:
|
case TGT_ENUM:
|
||||||
case TGT_BASIC:
|
case TGT_BASIC:
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
|
@ -3085,7 +3118,8 @@ static unsigned int process_tfs_stmts(FILE *file, const statement_list_t *stmts,
|
||||||
STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(iface) )
|
STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(iface) )
|
||||||
{
|
{
|
||||||
const var_t *func = stmt_func->u.var;
|
const var_t *func = stmt_func->u.var;
|
||||||
if (is_local(func->attrs)) continue;
|
current_func = func;
|
||||||
|
if (is_local(func->attrs)) continue;
|
||||||
|
|
||||||
if (!is_void(type_function_get_rettype(func->type)))
|
if (!is_void(type_function_get_rettype(func->type)))
|
||||||
{
|
{
|
||||||
|
@ -4150,20 +4184,46 @@ int write_expr_eval_routines(FILE *file, const char *iface)
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
|
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
|
||||||
{
|
{
|
||||||
const char *name = eval->structure->name;
|
const char *name = eval->name;
|
||||||
result = 1;
|
result = 1;
|
||||||
|
|
||||||
print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
|
print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
|
||||||
iface, name, callback_offset);
|
iface, name, callback_offset);
|
||||||
print_file(file, 0, "{\n");
|
print_file(file, 0, "{\n");
|
||||||
print_file(file, 1, "%s", "");
|
if (type_get_type( eval->cont_type ) == TYPE_FUNCTION)
|
||||||
write_type_left(file, (type_t *)eval->structure, TRUE);
|
{
|
||||||
fprintf(file, " *%s = (", var_name);
|
const var_list_t *args = type_get_function_args( eval->cont_type );
|
||||||
write_type_left(file, (type_t *)eval->structure, TRUE);
|
const var_t *arg;
|
||||||
fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
|
|
||||||
|
print_file(file, 1, "struct _PARAM_STRUCT\n" );
|
||||||
|
print_file(file, 1, "{\n" );
|
||||||
|
if (is_object( eval->iface )) print_file(file, 2, "%s *This;\n", eval->iface->name );
|
||||||
|
|
||||||
|
if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
|
||||||
|
{
|
||||||
|
print_file(file, 2, "%s", "");
|
||||||
|
write_type_left( file, (type_t *)arg->type, TRUE );
|
||||||
|
if (needs_space_after( arg->type )) fputc( ' ', file );
|
||||||
|
if (is_array( arg->type ) && !type_array_is_decl_as_ptr( arg->type )) fputc( '*', file );
|
||||||
|
/* FIXME: should check for large args being passed by pointer */
|
||||||
|
if (is_array( arg->type ) || is_ptr( arg->type ) || type_memsize( arg->type ) == pointer_size)
|
||||||
|
fprintf( file, "%s;\n", arg->name );
|
||||||
|
else
|
||||||
|
fprintf( file, "%s DECLSPEC_ALIGN(%u);\n", arg->name, pointer_size );
|
||||||
|
}
|
||||||
|
print_file(file, 1, "} *pS = (struct _PARAM_STRUCT *)pStubMsg->StackTop;\n" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_file(file, 1, "%s", "");
|
||||||
|
write_type_left(file, (type_t *)eval->cont_type, TRUE);
|
||||||
|
fprintf(file, " *%s = (", var_name);
|
||||||
|
write_type_left(file, (type_t *)eval->cont_type, TRUE);
|
||||||
|
fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff);
|
||||||
|
}
|
||||||
print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
|
print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
|
||||||
print_file(file, 1, "pStubMsg->MaxCount = (ULONG_PTR)");
|
print_file(file, 1, "pStubMsg->MaxCount = (ULONG_PTR)");
|
||||||
write_expr(file, eval->expr, 1, 1, var_name_expr, eval->structure, "");
|
write_expr(file, eval->expr, 1, 1, var_name_expr, eval->cont_type, "");
|
||||||
fprintf(file, ";\n");
|
fprintf(file, ";\n");
|
||||||
print_file(file, 0, "}\n\n");
|
print_file(file, 0, "}\n\n");
|
||||||
callback_offset++;
|
callback_offset++;
|
||||||
|
@ -4182,10 +4242,10 @@ void write_expr_eval_routine_list(FILE *file, const char *iface)
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry)
|
LIST_FOR_EACH_ENTRY_SAFE(eval, cursor, &expr_eval_routines, struct expr_eval_routine, entry)
|
||||||
{
|
{
|
||||||
const char *name = eval->structure->name;
|
print_file(file, 1, "%s_%sExprEval_%04u,\n", iface, eval->name, callback_offset);
|
||||||
print_file(file, 1, "%s_%sExprEval_%04u,\n", iface, name, callback_offset);
|
|
||||||
callback_offset++;
|
callback_offset++;
|
||||||
list_remove(&eval->entry);
|
list_remove(&eval->entry);
|
||||||
|
free(eval->name);
|
||||||
free(eval);
|
free(eval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ int line_number = 1;
|
||||||
|
|
||||||
static FILE *idfile;
|
static FILE *idfile;
|
||||||
|
|
||||||
size_t pointer_size = 0;
|
unsigned int pointer_size = 0;
|
||||||
syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
|
syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
|
||||||
|
|
||||||
time_t now;
|
time_t now;
|
||||||
|
|
|
@ -66,7 +66,7 @@ extern char *regscript_name;
|
||||||
extern char *regscript_token;
|
extern char *regscript_token;
|
||||||
extern const char *prefix_client;
|
extern const char *prefix_client;
|
||||||
extern const char *prefix_server;
|
extern const char *prefix_server;
|
||||||
extern size_t pointer_size;
|
extern unsigned int pointer_size;
|
||||||
extern time_t now;
|
extern time_t now;
|
||||||
|
|
||||||
extern int line_number;
|
extern int line_number;
|
||||||
|
|
Loading…
Reference in New Issue