widl: Pass variables around instead of types for function parameters.

This commit is contained in:
Alexandre Julliard 2011-09-19 11:54:42 +02:00
parent c31948a775
commit e2a92702ed
1 changed files with 49 additions and 57 deletions

View File

@ -413,12 +413,12 @@ static int get_padding(const var_list_t *fields)
return ROUNDING(offset, salign); return ROUNDING(offset, salign);
} }
static unsigned int get_stack_size( const type_t *type, const attr_list_t *attrs, int *by_value ) static unsigned int get_stack_size( const var_t *var, int *by_value )
{ {
unsigned int stack_size; unsigned int stack_size;
int by_val; int by_val;
switch (typegen_detect_type( type, attrs, TDT_ALL_TYPES )) switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
{ {
case TGT_BASIC: case TGT_BASIC:
case TGT_ENUM: case TGT_ENUM:
@ -426,7 +426,7 @@ static unsigned int get_stack_size( const type_t *type, const attr_list_t *attrs
case TGT_STRUCT: case TGT_STRUCT:
case TGT_UNION: case TGT_UNION:
case TGT_USER_TYPE: case TGT_USER_TYPE:
stack_size = type_memsize( type ); stack_size = type_memsize( var->type );
by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */ by_val = (pointer_size < 8 || stack_size <= pointer_size); /* FIXME: should be platform-specific */
break; break;
default: default:
@ -952,35 +952,34 @@ int decl_indirect(const type_t *t)
type_get_type(t) != TYPE_ARRAY); type_get_type(t) != TYPE_ARRAY);
} }
static unsigned char get_parameter_fc( const type_t *type, const attr_list_t *attrs, int is_return, static unsigned char get_parameter_fc( const var_t *var, int is_return, unsigned short *flags,
unsigned short *flags, unsigned int *stack_size, unsigned int *stack_size, unsigned int *typestring_offset )
unsigned int *typestring_offset )
{ {
unsigned int alignment, server_size = 0, buffer_size = 0; unsigned int alignment, server_size = 0, buffer_size = 0;
unsigned char fc = 0; unsigned char fc = 0;
int is_byval; int is_byval;
int is_in = is_attr(attrs, ATTR_IN); int is_in = is_attr(var->attrs, ATTR_IN);
int is_out = is_attr(attrs, ATTR_OUT); int is_out = is_attr(var->attrs, ATTR_OUT);
if (is_return) is_out = TRUE; if (is_return) is_out = TRUE;
else if (!is_in && !is_out) is_in = TRUE; else if (!is_in && !is_out) is_in = TRUE;
*flags = 0; *flags = 0;
*stack_size = get_stack_size( type, attrs, &is_byval ); *stack_size = get_stack_size( var, &is_byval );
*typestring_offset = type->typestring_offset; *typestring_offset = var->type->typestring_offset;
if (is_in) *flags |= IsIn; if (is_in) *flags |= IsIn;
if (is_out) *flags |= IsOut; if (is_out) *flags |= IsOut;
if (is_return) *flags |= IsReturn; if (is_return) *flags |= IsReturn;
if (!is_string_type( attrs, type )) if (!is_string_type( var->attrs, var->type ))
buffer_size = get_required_buffer_size_type( type, NULL, attrs, TRUE, &alignment ); buffer_size = get_required_buffer_size_type( var->type, NULL, var->attrs, TRUE, &alignment );
switch (typegen_detect_type( type, attrs, TDT_ALL_TYPES )) switch (typegen_detect_type( var->type, var->attrs, TDT_ALL_TYPES ))
{ {
case TGT_BASIC: case TGT_BASIC:
*flags |= IsBasetype; *flags |= IsBasetype;
fc = get_basic_fc_signed( type ); fc = get_basic_fc_signed( var->type );
if (fc == RPC_FC_BIND_PRIMITIVE) if (fc == RPC_FC_BIND_PRIMITIVE)
{ {
buffer_size = 4; /* actually 0 but avoids setting MustSize */ buffer_size = 4; /* actually 0 but avoids setting MustSize */
@ -989,7 +988,7 @@ static unsigned char get_parameter_fc( const type_t *type, const attr_list_t *at
break; break;
case TGT_ENUM: case TGT_ENUM:
*flags |= IsBasetype; *flags |= IsBasetype;
fc = get_enum_fc( type ); fc = get_enum_fc( var->type );
break; break;
case TGT_RANGE: case TGT_RANGE:
*flags |= IsByValue; *flags |= IsByValue;
@ -1004,16 +1003,16 @@ static unsigned char get_parameter_fc( const type_t *type, const attr_list_t *at
break; break;
case TGT_ARRAY: case TGT_ARRAY:
*flags |= MustFree; *flags |= MustFree;
if (type_array_is_decl_as_ptr(type) && type->details.array.ptr_tfsoff && if (type_array_is_decl_as_ptr(var->type) && var->type->details.array.ptr_tfsoff &&
get_pointer_fc( type, attrs, !is_return ) == RPC_FC_RP) get_pointer_fc( var->type, var->attrs, !is_return ) == RPC_FC_RP)
*flags |= IsSimpleRef; *flags |= IsSimpleRef;
break; break;
case TGT_STRING: case TGT_STRING:
*flags |= MustFree; *flags |= MustFree;
if (is_declptr( type ) && get_pointer_fc( type, attrs, !is_return ) == RPC_FC_RP) if (is_declptr( var->type ) && get_pointer_fc( var->type, var->attrs, !is_return ) == RPC_FC_RP)
{ {
/* skip over pointer description straight to string description */ /* skip over pointer description straight to string description */
if (is_conformant_array( type )) *typestring_offset += 4; if (is_conformant_array( var->type )) *typestring_offset += 4;
else *typestring_offset += 2; else *typestring_offset += 2;
*flags |= IsSimpleRef; *flags |= IsSimpleRef;
} }
@ -1026,11 +1025,11 @@ static unsigned char get_parameter_fc( const type_t *type, const attr_list_t *at
buffer_size = 20; buffer_size = 20;
break; break;
case TGT_POINTER: case TGT_POINTER:
if (get_pointer_fc( type, attrs, !is_return ) == RPC_FC_RP) if (get_pointer_fc( var->type, var->attrs, !is_return ) == RPC_FC_RP)
{ {
const type_t *ref = type_pointer_get_ref( type ); const type_t *ref = type_pointer_get_ref( var->type );
if (!is_string_type( attrs, ref )) if (!is_string_type( var->attrs, ref ))
buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment ); buffer_size = get_required_buffer_size_type( ref, NULL, NULL, TRUE, &alignment );
switch (typegen_detect_type( ref, NULL, TDT_ALL_TYPES )) switch (typegen_detect_type( ref, NULL, TDT_ALL_TYPES ))
@ -1111,14 +1110,14 @@ static unsigned char get_func_oi2_flags( const var_t *func )
{ {
const var_t *var; const var_t *var;
var_list_t *args = type_get_function_args( func->type ); var_list_t *args = type_get_function_args( func->type );
type_t *ret_type = type_function_get_rettype( func->type ); var_t *retval = type_function_get_retval( func->type );
unsigned char oi2_flags = 0x40; /* HasExtensions */ unsigned char oi2_flags = 0x40; /* HasExtensions */
unsigned short flags; unsigned short flags;
unsigned int stack_size, typestring_offset; unsigned int stack_size, typestring_offset;
if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry ) if (args) LIST_FOR_EACH_ENTRY( var, args, const var_t, entry )
{ {
get_parameter_fc( var->type, var->attrs, 0, &flags, &stack_size, &typestring_offset ); get_parameter_fc( var, 0, &flags, &stack_size, &typestring_offset );
if (flags & MustSize) if (flags & MustSize)
{ {
if (flags & IsIn) oi2_flags |= 0x02; /* ClientMustSize */ if (flags & IsIn) oi2_flags |= 0x02; /* ClientMustSize */
@ -1126,24 +1125,22 @@ static unsigned char get_func_oi2_flags( const var_t *func )
} }
} }
if (!is_void( ret_type )) if (!is_void( retval->type ))
{ {
oi2_flags |= 0x04; /* HasRet */ oi2_flags |= 0x04; /* HasRet */
get_parameter_fc( ret_type, NULL, 1, &flags, &stack_size, &typestring_offset ); get_parameter_fc( retval, 1, &flags, &stack_size, &typestring_offset );
if (flags & MustSize) oi2_flags |= 0x01; /* ServerMustSize */ if (flags & MustSize) oi2_flags |= 0x01; /* ServerMustSize */
} }
return oi2_flags; return oi2_flags;
} }
static unsigned int write_new_procformatstring_type(FILE *file, int indent, static unsigned int write_new_procformatstring_type(FILE *file, int indent, const var_t *var,
const type_t *type,
const attr_list_t *attrs,
int is_return, unsigned int *stack_offset) int is_return, unsigned int *stack_offset)
{ {
char buffer[64]; char buffer[64];
unsigned int stack_size, typestring_offset; unsigned int stack_size, typestring_offset;
unsigned short flags; unsigned short flags;
unsigned char fc = get_parameter_fc( type, attrs, is_return, &flags, &stack_size, &typestring_offset ); unsigned char fc = get_parameter_fc( var, is_return, &flags, &stack_size, &typestring_offset );
strcpy( buffer, "/* flags:" ); strcpy( buffer, "/* flags:" );
if (flags & MustSize) strcat( buffer, " must size," ); if (flags & MustSize) strcat( buffer, " must size," );
@ -1172,20 +1169,18 @@ static unsigned int write_new_procformatstring_type(FILE *file, int indent,
return 6; return 6;
} }
static unsigned int write_old_procformatstring_type(FILE *file, int indent, static unsigned int write_old_procformatstring_type(FILE *file, int indent, const var_t *var,
const type_t *type,
const attr_list_t *attrs,
int is_return, int is_interpreted) int is_return, int is_interpreted)
{ {
unsigned int size; unsigned int size;
int is_in = is_attr(attrs, ATTR_IN); int is_in = is_attr(var->attrs, ATTR_IN);
int is_out = is_attr(attrs, ATTR_OUT); int is_out = is_attr(var->attrs, ATTR_OUT);
if (!is_in && !is_out) is_in = TRUE; if (!is_in && !is_out) is_in = TRUE;
if (type_get_type(type) == TYPE_BASIC || if (type_get_type(var->type) == TYPE_BASIC ||
type_get_type(type) == TYPE_ENUM) type_get_type(var->type) == TYPE_ENUM)
{ {
unsigned char fc; unsigned char fc;
@ -1194,13 +1189,13 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent,
else else
print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n"); print_file(file, indent, "0x4e, /* FC_IN_PARAM_BASETYPE */\n");
if (type_get_type(type) == TYPE_ENUM) if (type_get_type(var->type) == TYPE_ENUM)
{ {
fc = get_enum_fc(type); fc = get_enum_fc(var->type);
} }
else else
{ {
fc = get_basic_fc_signed(type); fc = get_basic_fc_signed(var->type);
if (fc == RPC_FC_BIND_PRIMITIVE) if (fc == RPC_FC_BIND_PRIMITIVE)
fc = RPC_FC_IGNORE; fc = RPC_FC_IGNORE;
@ -1212,12 +1207,12 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent,
} }
else else
{ {
unsigned short offset = type->typestring_offset; unsigned short offset = var->type->typestring_offset;
if (is_interpreted && is_array(type) && if (is_interpreted && is_array(var->type) &&
type_array_is_decl_as_ptr(type) && type_array_is_decl_as_ptr(var->type) &&
type->details.array.ptr_tfsoff) var->type->details.array.ptr_tfsoff)
offset = type->details.array.ptr_tfsoff; offset = var->type->details.array.ptr_tfsoff;
if (is_return) if (is_return)
print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n"); print_file(file, indent, "0x52, /* FC_RETURN_PARAM */\n");
@ -1228,7 +1223,7 @@ static unsigned int write_old_procformatstring_type(FILE *file, int indent,
else else
print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n"); print_file(file, indent, "0x4d, /* FC_IN_PARAM */\n");
size = get_stack_size( type, attrs, NULL ); size = get_stack_size( var, NULL );
print_file(file, indent, "0x%02x,\n", size / pointer_size ); print_file(file, indent, "0x%02x,\n", size / pointer_size );
print_file(file, indent, "NdrFcShort(0x%x), /* type offset = %u */\n", offset, offset); print_file(file, indent, "NdrFcShort(0x%x), /* type offset = %u */\n", offset, offset);
size = 4; /* includes param type prefix */ size = 4; /* includes param type prefix */
@ -1318,7 +1313,7 @@ static void write_proc_func_header( FILE *file, int indent, const type_t *iface,
handle_stack_offset = stack_size; handle_stack_offset = stack_size;
handle_param_num = param_num; handle_param_num = param_num;
} }
stack_size += get_stack_size( var->type, var->attrs, NULL ); stack_size += get_stack_size( var, NULL );
param_num++; param_num++;
nb_args++; nb_args++;
} }
@ -1425,6 +1420,7 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
unsigned int stack_offset = is_object( iface ) ? pointer_size : 0; unsigned int stack_offset = is_object( iface ) ? pointer_size : 0;
int is_interpreted = is_interpreted_func( iface, func ); int is_interpreted = is_interpreted_func( iface, func );
int is_new_style = is_interpreted && (get_stub_mode() == MODE_Oif); int is_new_style = is_interpreted && (get_stub_mode() == MODE_Oif);
var_t *retval = type_function_get_retval( func->type );
if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc ); if (is_interpreted) write_proc_func_header( file, indent, iface, func, offset, num_proc );
@ -1436,16 +1432,14 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
{ {
print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name ); print_file( file, 0, "/* %u (parameter %s) */\n", *offset, var->name );
if (is_new_style) if (is_new_style)
*offset += write_new_procformatstring_type(file, indent, var->type, var->attrs, *offset += write_new_procformatstring_type(file, indent, var, FALSE, &stack_offset);
FALSE, &stack_offset);
else else
*offset += write_old_procformatstring_type(file, indent, var->type, var->attrs, *offset += write_old_procformatstring_type(file, indent, var, FALSE, is_interpreted);
FALSE, is_interpreted);
} }
} }
/* emit return value data */ /* emit return value data */
if (is_void(type_function_get_rettype(func->type))) if (is_void(retval->type))
{ {
if (!is_new_style) if (!is_new_style)
{ {
@ -1459,11 +1453,9 @@ static void write_procformatstring_func( FILE *file, int indent, const type_t *i
{ {
print_file( file, 0, "/* %u (return value) */\n", *offset ); print_file( file, 0, "/* %u (return value) */\n", *offset );
if (is_new_style) if (is_new_style)
*offset += write_new_procformatstring_type(file, indent, type_function_get_rettype(func->type), *offset += write_new_procformatstring_type(file, indent, retval, TRUE, &stack_offset);
NULL, TRUE, &stack_offset);
else else
*offset += write_old_procformatstring_type(file, indent, type_function_get_rettype(func->type), *offset += write_old_procformatstring_type(file, indent, retval, TRUE, is_interpreted);
NULL, TRUE, is_interpreted);
} }
} }
@ -1659,7 +1651,7 @@ static unsigned int write_conf_or_var_desc(FILE *file, const type_t *cont_type,
correlation_variable = var->type; correlation_variable = var->type;
break; break;
} }
offset += get_stack_size( var->type, var->attrs, NULL ); offset += get_stack_size( var, NULL );
} }
} }
else else