widl: Add typegen_detect_type and use it.
Add typegen_detect_type for detecting types useful during client/server/proxy code generation.
This commit is contained in:
parent
af0800729b
commit
2c6e611c8a
@ -2342,8 +2342,7 @@ static void check_field_common(const type_t *container_type,
|
|||||||
const char *container_name, const var_t *arg)
|
const char *container_name, const var_t *arg)
|
||||||
{
|
{
|
||||||
type_t *type = arg->type;
|
type_t *type = arg->type;
|
||||||
int is_wire_marshal = 0;
|
int more_to_do;
|
||||||
int is_context_handle = 0;
|
|
||||||
const char *container_type_name = NULL;
|
const char *container_type_name = NULL;
|
||||||
|
|
||||||
switch (type_get_type_detect_alias(type))
|
switch (type_get_type_detect_alias(type))
|
||||||
@ -2410,35 +2409,56 @@ static void check_field_common(const type_t *container_type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get fundamental type for the argument */
|
do
|
||||||
for (;;)
|
|
||||||
{
|
{
|
||||||
if (is_attr(type->attrs, ATTR_WIREMARSHAL))
|
more_to_do = FALSE;
|
||||||
{
|
|
||||||
is_wire_marshal = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
|
|
||||||
{
|
|
||||||
is_context_handle = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (type_is_alias(type))
|
|
||||||
type = type_alias_get_aliasee(type);
|
|
||||||
else if (is_ptr(type))
|
|
||||||
type = type_pointer_get_ref(type);
|
|
||||||
else if (is_array(type))
|
|
||||||
type = type_array_get_element(type);
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type_get_type(type) == TYPE_VOID && !is_attr(arg->attrs, ATTR_IIDIS) && !is_wire_marshal && !is_context_handle)
|
switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
|
||||||
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n", arg->name, container_type_name, container_name);
|
{
|
||||||
else if (type_get_type(type) == TYPE_FUNCTION)
|
case TGT_STRUCT:
|
||||||
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n", arg->name, container_type_name, container_name);
|
case TGT_UNION:
|
||||||
else if (!is_wire_marshal && (type_get_type(type) == TYPE_STRUCT || type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION))
|
check_remoting_fields(arg, type);
|
||||||
check_remoting_fields(arg, type);
|
break;
|
||||||
|
case TGT_INVALID:
|
||||||
|
switch (type_get_type(type))
|
||||||
|
{
|
||||||
|
case TYPE_VOID:
|
||||||
|
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n",
|
||||||
|
arg->name, container_type_name, container_name);
|
||||||
|
break;
|
||||||
|
case TYPE_FUNCTION:
|
||||||
|
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n",
|
||||||
|
arg->name, container_type_name, container_name);
|
||||||
|
break;
|
||||||
|
case TYPE_COCLASS:
|
||||||
|
case TYPE_INTERFACE:
|
||||||
|
case TYPE_MODULE:
|
||||||
|
/* FIXME */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
/* FIXME */
|
||||||
|
break;
|
||||||
|
case TGT_POINTER:
|
||||||
|
type = type_pointer_get_ref(type);
|
||||||
|
more_to_do = TRUE;
|
||||||
|
break;
|
||||||
|
case TGT_ARRAY:
|
||||||
|
type = type_array_get_element(type);
|
||||||
|
more_to_do = TRUE;
|
||||||
|
break;
|
||||||
|
case TGT_USER_TYPE:
|
||||||
|
case TGT_STRING:
|
||||||
|
case TGT_IFACE_POINTER:
|
||||||
|
case TGT_BASIC:
|
||||||
|
case TGT_ENUM:
|
||||||
|
/* nothing to do */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (more_to_do);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_remoting_fields(const var_t *var, type_t *type)
|
static void check_remoting_fields(const var_t *var, type_t *type)
|
||||||
@ -2475,36 +2495,37 @@ static void check_remoting_args(const var_t *func)
|
|||||||
|
|
||||||
if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
|
if (func->type->details.function->args) LIST_FOR_EACH_ENTRY( arg, func->type->details.function->args, const var_t, entry )
|
||||||
{
|
{
|
||||||
int ptr_level = 0;
|
|
||||||
const type_t *type = arg->type;
|
const type_t *type = arg->type;
|
||||||
|
|
||||||
/* get pointer level and fundamental type for the argument */
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (is_attr(type->attrs, ATTR_WIREMARSHAL))
|
|
||||||
break;
|
|
||||||
if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
|
|
||||||
break;
|
|
||||||
if (type_is_alias(type))
|
|
||||||
type = type_alias_get_aliasee(type);
|
|
||||||
else if (is_ptr(type))
|
|
||||||
{
|
|
||||||
ptr_level++;
|
|
||||||
type = type_pointer_get_ref(type);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check that [out] parameters have enough pointer levels */
|
/* check that [out] parameters have enough pointer levels */
|
||||||
if (is_attr(arg->attrs, ATTR_OUT))
|
if (is_attr(arg->attrs, ATTR_OUT))
|
||||||
{
|
{
|
||||||
if (!is_array(type))
|
switch (typegen_detect_type(type, arg->attrs, TDT_ALL_TYPES))
|
||||||
{
|
{
|
||||||
if (!ptr_level)
|
case TGT_BASIC:
|
||||||
error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
|
case TGT_ENUM:
|
||||||
if (type_get_type(type) == TYPE_INTERFACE && ptr_level == 1)
|
case TGT_STRUCT:
|
||||||
error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
|
case TGT_UNION:
|
||||||
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_USER_TYPE:
|
||||||
|
error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
|
||||||
|
break;
|
||||||
|
case TGT_IFACE_POINTER:
|
||||||
|
error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
|
||||||
|
break;
|
||||||
|
case TGT_STRING:
|
||||||
|
if (!is_array(type))
|
||||||
|
{
|
||||||
|
/* FIXME */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TGT_INVALID:
|
||||||
|
/* already error'd before we get here */
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
case TGT_POINTER:
|
||||||
|
case TGT_ARRAY:
|
||||||
|
/* OK */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,17 +153,20 @@ int is_var_ptr(const var_t *v)
|
|||||||
|
|
||||||
int cant_be_null(const var_t *v)
|
int cant_be_null(const var_t *v)
|
||||||
{
|
{
|
||||||
const type_t *type = v->type;
|
switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS))
|
||||||
|
{
|
||||||
|
case TGT_ARRAY:
|
||||||
|
/* FIXME: work out pointer type */
|
||||||
|
return 0;
|
||||||
|
case TGT_IFACE_POINTER: /* FIXME */
|
||||||
|
case TGT_POINTER:
|
||||||
|
return (get_pointer_fc(v->type) == RPC_FC_RP);
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* context handles have their own checking so they can be null for the
|
|
||||||
* purposes of null ref pointer checking */
|
|
||||||
if (is_aliaschain_attr(type, ATTR_CONTEXTHANDLE))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (is_user_type(type))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (get_pointer_fc(type) == RPC_FC_RP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int need_delegation(const type_t *iface)
|
static int need_delegation(const type_t *iface)
|
||||||
@ -225,28 +228,29 @@ static void free_variable( const var_t *arg, const char *local_var_prefix )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type_get_type(type))
|
switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
|
||||||
{
|
{
|
||||||
case TYPE_ENUM:
|
case TGT_ENUM:
|
||||||
case TYPE_BASIC:
|
case TGT_BASIC:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_STRUCT:
|
case TGT_STRUCT:
|
||||||
if (get_struct_fc(type) != RPC_FC_STRUCT)
|
if (get_struct_fc(type) != RPC_FC_STRUCT)
|
||||||
print_proxy("/* FIXME: %s code for %s type %d missing */\n", __FUNCTION__, arg->name, type_get_type(type) );
|
print_proxy("/* FIXME: %s code for %s struct type 0x%x missing */\n", __FUNCTION__, arg->name, get_struct_fc(type) );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TYPE_POINTER:
|
case TGT_IFACE_POINTER:
|
||||||
case TYPE_INTERFACE:
|
iid = get_attrp( arg->attrs, ATTR_IIDIS );
|
||||||
if (type_get_type(type) == TYPE_INTERFACE || get_pointer_fc(type) == RPC_FC_FP)
|
if( iid )
|
||||||
|
{
|
||||||
|
print_proxy( "__frame->_StubMsg.MaxCount = (ULONG_PTR) " );
|
||||||
|
write_expr(proxy, iid, 1, 1, NULL, NULL, local_var_prefix);
|
||||||
|
print_proxy( ";\n\n" );
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
|
case TGT_POINTER:
|
||||||
|
if (get_pointer_fc(type) == RPC_FC_FP)
|
||||||
{
|
{
|
||||||
iid = get_attrp( arg->attrs, ATTR_IIDIS );
|
|
||||||
if( iid )
|
|
||||||
{
|
|
||||||
print_proxy( "__frame->_StubMsg.MaxCount = (ULONG_PTR) " );
|
|
||||||
write_expr(proxy, iid, 1, 1, NULL, NULL, local_var_prefix);
|
|
||||||
print_proxy( ";\n\n" );
|
|
||||||
}
|
|
||||||
print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, ");
|
print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, ");
|
||||||
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
|
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
|
||||||
fprintf(proxy, "(void*)%s );\n", arg->name );
|
fprintf(proxy, "(void*)%s );\n", arg->name );
|
||||||
|
@ -138,6 +138,49 @@ static unsigned char get_enum_fc(const type_t *type)
|
|||||||
return RPC_FC_ENUM16;
|
return RPC_FC_ENUM16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags)
|
||||||
|
{
|
||||||
|
if (is_user_type(type))
|
||||||
|
return TGT_USER_TYPE;
|
||||||
|
|
||||||
|
if (is_aliaschain_attr(type, ATTR_CONTEXTHANDLE))
|
||||||
|
return TGT_CTXT_HANDLE;
|
||||||
|
|
||||||
|
if (!(flags & TDT_IGNORE_STRINGS) && is_string_type(attrs, type))
|
||||||
|
return TGT_STRING;
|
||||||
|
|
||||||
|
switch (type_get_type(type))
|
||||||
|
{
|
||||||
|
case TYPE_BASIC:
|
||||||
|
return TGT_BASIC;
|
||||||
|
case TYPE_ENUM:
|
||||||
|
return TGT_ENUM;
|
||||||
|
case TYPE_POINTER:
|
||||||
|
if (type_get_type(type_pointer_get_ref(type)) == TYPE_INTERFACE ||
|
||||||
|
(type_get_type(type_pointer_get_ref(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
|
||||||
|
return TGT_IFACE_POINTER;
|
||||||
|
else if (is_aliaschain_attr(type_pointer_get_ref(type), ATTR_CONTEXTHANDLE))
|
||||||
|
return TGT_CTXT_HANDLE_POINTER;
|
||||||
|
else
|
||||||
|
return TGT_POINTER;
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
return TGT_STRUCT;
|
||||||
|
case TYPE_ENCAPSULATED_UNION:
|
||||||
|
case TYPE_UNION:
|
||||||
|
return TGT_UNION;
|
||||||
|
case TYPE_ARRAY:
|
||||||
|
return TGT_ARRAY;
|
||||||
|
case TYPE_FUNCTION:
|
||||||
|
case TYPE_COCLASS:
|
||||||
|
case TYPE_INTERFACE:
|
||||||
|
case TYPE_MODULE:
|
||||||
|
case TYPE_VOID:
|
||||||
|
case TYPE_ALIAS:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TGT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char get_struct_fc(const type_t *type)
|
unsigned char get_struct_fc(const type_t *type)
|
||||||
{
|
{
|
||||||
int has_pointer = 0;
|
int has_pointer = 0;
|
||||||
@ -154,11 +197,11 @@ unsigned char get_struct_fc(const type_t *type)
|
|||||||
if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry )
|
if (fields) LIST_FOR_EACH_ENTRY( field, fields, var_t, entry )
|
||||||
{
|
{
|
||||||
type_t *t = field->type;
|
type_t *t = field->type;
|
||||||
|
enum typegen_type typegen_type;
|
||||||
|
|
||||||
if (is_user_type(t))
|
typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
|
||||||
return RPC_FC_BOGUS_STRUCT;
|
|
||||||
|
|
||||||
if (t->declarray)
|
if (typegen_type == TGT_ARRAY && t->declarray)
|
||||||
{
|
{
|
||||||
if (is_string_type(field->attrs, field->type))
|
if (is_string_type(field->attrs, field->type))
|
||||||
{
|
{
|
||||||
@ -182,32 +225,26 @@ unsigned char get_struct_fc(const type_t *type)
|
|||||||
has_variance = 1;
|
has_variance = 1;
|
||||||
|
|
||||||
t = type_array_get_element(t);
|
t = type_array_get_element(t);
|
||||||
|
typegen_type = typegen_detect_type(t, field->attrs, TDT_IGNORE_STRINGS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_user_type(t))
|
switch (typegen_type)
|
||||||
return RPC_FC_BOGUS_STRUCT;
|
|
||||||
|
|
||||||
switch (type_get_type(t))
|
|
||||||
{
|
{
|
||||||
case TYPE_VOID:
|
case TGT_USER_TYPE:
|
||||||
case TYPE_ALIAS:
|
case TGT_IFACE_POINTER:
|
||||||
case TYPE_MODULE:
|
return RPC_FC_BOGUS_STRUCT;
|
||||||
assert(0);
|
case TGT_BASIC:
|
||||||
break;
|
break;
|
||||||
case TYPE_BASIC:
|
case TGT_ENUM:
|
||||||
break;
|
|
||||||
case TYPE_ENUM:
|
|
||||||
if (get_enum_fc(t) == RPC_FC_ENUM16)
|
if (get_enum_fc(t) == RPC_FC_ENUM16)
|
||||||
return RPC_FC_BOGUS_STRUCT;
|
return RPC_FC_BOGUS_STRUCT;
|
||||||
break;
|
break;
|
||||||
case TYPE_POINTER:
|
case TGT_POINTER:
|
||||||
if (get_pointer_fc(t) == RPC_FC_RP || pointer_size != 4)
|
if (get_pointer_fc(t) == RPC_FC_RP || pointer_size != 4)
|
||||||
return RPC_FC_BOGUS_STRUCT;
|
return RPC_FC_BOGUS_STRUCT;
|
||||||
if (type_get_type(type_pointer_get_ref(t)) == TYPE_INTERFACE)
|
|
||||||
return RPC_FC_BOGUS_STRUCT;
|
|
||||||
has_pointer = 1;
|
has_pointer = 1;
|
||||||
break;
|
break;
|
||||||
case TYPE_ARRAY:
|
case TGT_ARRAY:
|
||||||
{
|
{
|
||||||
unsigned int ptr_type = get_attrv(field->attrs, ATTR_POINTERTYPE);
|
unsigned int ptr_type = get_attrv(field->attrs, ATTR_POINTERTYPE);
|
||||||
if (!ptr_type || ptr_type == RPC_FC_RP)
|
if (!ptr_type || ptr_type == RPC_FC_RP)
|
||||||
@ -217,13 +254,9 @@ unsigned char get_struct_fc(const type_t *type)
|
|||||||
has_pointer = 1;
|
has_pointer = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_INTERFACE:
|
case TGT_UNION:
|
||||||
case TYPE_UNION:
|
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
|
||||||
case TYPE_COCLASS:
|
|
||||||
case TYPE_FUNCTION:
|
|
||||||
return RPC_FC_BOGUS_STRUCT;
|
return RPC_FC_BOGUS_STRUCT;
|
||||||
case TYPE_STRUCT:
|
case TGT_STRUCT:
|
||||||
{
|
{
|
||||||
unsigned char fc = get_struct_fc(t);
|
unsigned char fc = get_struct_fc(t);
|
||||||
switch (fc)
|
switch (fc)
|
||||||
@ -265,6 +298,14 @@ unsigned char get_struct_fc(const type_t *type)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TGT_STRING:
|
||||||
|
/* shouldn't get here because of TDT_IGNORE_STRINGS above. fall through */
|
||||||
|
case TGT_INVALID:
|
||||||
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
/* checking after parsing should mean that we don't get here. if we do,
|
||||||
|
* it's a checker bug */
|
||||||
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,11 +356,12 @@ unsigned char get_array_fc(const type_t *type)
|
|||||||
fc = RPC_FC_CVARRAY;
|
fc = RPC_FC_CVARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_user_type(elem_type))
|
switch (typegen_detect_type(elem_type, NULL, TDT_IGNORE_STRINGS))
|
||||||
fc = RPC_FC_BOGUS_ARRAY;
|
|
||||||
else switch (type_get_type(elem_type))
|
|
||||||
{
|
{
|
||||||
case TYPE_STRUCT:
|
case TGT_USER_TYPE:
|
||||||
|
fc = RPC_FC_BOGUS_ARRAY;
|
||||||
|
break;
|
||||||
|
case TGT_STRUCT:
|
||||||
switch (get_struct_fc(elem_type))
|
switch (get_struct_fc(elem_type))
|
||||||
{
|
{
|
||||||
case RPC_FC_BOGUS_STRUCT:
|
case RPC_FC_BOGUS_STRUCT:
|
||||||
@ -327,25 +369,29 @@ unsigned char get_array_fc(const type_t *type)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_ENUM:
|
case TGT_ENUM:
|
||||||
/* is 16-bit enum - if so, wire size differs from mem size and so
|
/* is 16-bit enum - if so, wire size differs from mem size and so
|
||||||
* the array cannot be block copied, which means the array is complex */
|
* the array cannot be block copied, which means the array is complex */
|
||||||
if (get_enum_fc(elem_type) == RPC_FC_ENUM16)
|
if (get_enum_fc(elem_type) == RPC_FC_ENUM16)
|
||||||
fc = RPC_FC_BOGUS_ARRAY;
|
fc = RPC_FC_BOGUS_ARRAY;
|
||||||
break;
|
break;
|
||||||
case TYPE_UNION:
|
case TGT_UNION:
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
case TGT_IFACE_POINTER:
|
||||||
fc = RPC_FC_BOGUS_ARRAY;
|
fc = RPC_FC_BOGUS_ARRAY;
|
||||||
break;
|
break;
|
||||||
case TYPE_POINTER:
|
case TGT_POINTER:
|
||||||
/* ref pointers cannot just be block copied. unique pointers to
|
/* ref pointers cannot just be block copied. unique pointers to
|
||||||
* interfaces need special treatment. either case means the array is
|
* interfaces need special treatment. either case means the array is
|
||||||
* complex */
|
* complex */
|
||||||
if (get_pointer_fc(elem_type) == RPC_FC_RP ||
|
if (get_pointer_fc(elem_type) == RPC_FC_RP)
|
||||||
type_get_type(type_pointer_get_ref(elem_type)) == TYPE_INTERFACE)
|
|
||||||
fc = RPC_FC_BOGUS_ARRAY;
|
fc = RPC_FC_BOGUS_ARRAY;
|
||||||
break;
|
break;
|
||||||
default:
|
case TGT_BASIC:
|
||||||
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
case TGT_STRING:
|
||||||
|
case TGT_INVALID:
|
||||||
|
case TGT_ARRAY:
|
||||||
/* nothing to do for everything else */
|
/* nothing to do for everything else */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -377,16 +423,16 @@ static int is_non_complex_struct(const type_t *type)
|
|||||||
|
|
||||||
static int type_has_pointers(const type_t *type)
|
static int type_has_pointers(const type_t *type)
|
||||||
{
|
{
|
||||||
if (is_user_type(type))
|
switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS))
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (type_get_type(type))
|
|
||||||
{
|
{
|
||||||
case TYPE_POINTER:
|
case TGT_USER_TYPE:
|
||||||
|
return FALSE;
|
||||||
|
case TGT_POINTER:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case TYPE_ARRAY:
|
case TGT_ARRAY:
|
||||||
|
/* FIXME: array can be pointer */
|
||||||
return type_has_pointers(type_array_get_element(type));
|
return type_has_pointers(type_array_get_element(type));
|
||||||
case TYPE_STRUCT:
|
case TGT_STRUCT:
|
||||||
{
|
{
|
||||||
var_list_t *fields = type_struct_get_fields(type);
|
var_list_t *fields = type_struct_get_fields(type);
|
||||||
const var_t *field;
|
const var_t *field;
|
||||||
@ -397,8 +443,7 @@ static int type_has_pointers(const type_t *type)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_UNION:
|
case TGT_UNION:
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
|
||||||
{
|
{
|
||||||
var_list_t *fields;
|
var_list_t *fields;
|
||||||
const var_t *field;
|
const var_t *field;
|
||||||
@ -410,7 +455,13 @@ static int type_has_pointers(const type_t *type)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
case TGT_STRING:
|
||||||
|
case TGT_IFACE_POINTER:
|
||||||
|
case TGT_BASIC:
|
||||||
|
case TGT_ENUM:
|
||||||
|
case TGT_INVALID:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,19 +470,19 @@ static int type_has_pointers(const type_t *type)
|
|||||||
|
|
||||||
static int type_has_full_pointer(const type_t *type)
|
static int type_has_full_pointer(const type_t *type)
|
||||||
{
|
{
|
||||||
if (is_user_type(type))
|
switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS))
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
switch (type_get_type(type))
|
|
||||||
{
|
{
|
||||||
case TYPE_POINTER:
|
case TGT_USER_TYPE:
|
||||||
|
return FALSE;
|
||||||
|
case TGT_POINTER:
|
||||||
if (get_pointer_fc(type) == RPC_FC_FP)
|
if (get_pointer_fc(type) == RPC_FC_FP)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
case TYPE_ARRAY:
|
case TGT_ARRAY:
|
||||||
|
/* FIXME: array can be full pointer */
|
||||||
return type_has_full_pointer(type_array_get_element(type));
|
return type_has_full_pointer(type_array_get_element(type));
|
||||||
case TYPE_STRUCT:
|
case TGT_STRUCT:
|
||||||
{
|
{
|
||||||
var_list_t *fields = type_struct_get_fields(type);
|
var_list_t *fields = type_struct_get_fields(type);
|
||||||
const var_t *field;
|
const var_t *field;
|
||||||
@ -442,8 +493,7 @@ static int type_has_full_pointer(const type_t *type)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_UNION:
|
case TGT_UNION:
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
|
||||||
{
|
{
|
||||||
var_list_t *fields;
|
var_list_t *fields;
|
||||||
const var_t *field;
|
const var_t *field;
|
||||||
@ -455,7 +505,13 @@ static int type_has_full_pointer(const type_t *type)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
case TGT_STRING:
|
||||||
|
case TGT_IFACE_POINTER:
|
||||||
|
case TGT_BASIC:
|
||||||
|
case TGT_ENUM:
|
||||||
|
case TGT_INVALID:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,18 +575,14 @@ 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)
|
||||||
{
|
{
|
||||||
if (is_user_type(type))
|
switch (typegen_detect_type(type, NULL, TDT_ALL_TYPES))
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
switch (type_get_type(type))
|
|
||||||
{
|
{
|
||||||
case TYPE_STRUCT:
|
case TGT_USER_TYPE:
|
||||||
case TYPE_UNION:
|
case TGT_STRUCT:
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
case TGT_UNION:
|
||||||
case TYPE_ARRAY:
|
case TGT_ARRAY:
|
||||||
|
case TGT_IFACE_POINTER:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case TYPE_POINTER:
|
|
||||||
return type_get_type(type_pointer_get_ref(type)) == TYPE_INTERFACE;
|
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -2567,19 +2619,17 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var
|
|||||||
{
|
{
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
|
|
||||||
if (is_context_handle(type))
|
switch (typegen_detect_type(type, var->attrs, TDT_ALL_TYPES))
|
||||||
return write_contexthandle_tfs(file, type, var, typeformat_offset);
|
|
||||||
|
|
||||||
if (is_user_type(type))
|
|
||||||
{
|
{
|
||||||
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
return write_contexthandle_tfs(file, type, var, typeformat_offset);
|
||||||
|
case TGT_USER_TYPE:
|
||||||
write_user_tfs(file, type, typeformat_offset);
|
write_user_tfs(file, type, typeformat_offset);
|
||||||
return type->typestring_offset;
|
return type->typestring_offset;
|
||||||
}
|
case TGT_STRING:
|
||||||
|
|
||||||
if (is_string_type(var->attrs, type))
|
|
||||||
return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset);
|
return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset);
|
||||||
|
case TGT_ARRAY:
|
||||||
if (is_array(type))
|
|
||||||
{
|
{
|
||||||
int ptr_type;
|
int ptr_type;
|
||||||
unsigned int off;
|
unsigned int off;
|
||||||
@ -2607,75 +2657,68 @@ static unsigned int write_typeformatstring_var(FILE *file, int indent, const var
|
|||||||
}
|
}
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
case TGT_STRUCT:
|
||||||
if (!is_ptr(type))
|
if (processed(type)) return type->typestring_offset;
|
||||||
{
|
return write_struct_tfs(file, type, var->name, typeformat_offset);
|
||||||
switch (type_get_type(type))
|
case TGT_UNION:
|
||||||
|
if (processed(type)) return type->typestring_offset;
|
||||||
|
return write_union_tfs(file, type, typeformat_offset);
|
||||||
|
case TGT_ENUM:
|
||||||
|
case TGT_BASIC:
|
||||||
|
/* nothing to do */
|
||||||
|
return 0;
|
||||||
|
case TGT_IFACE_POINTER:
|
||||||
|
return write_ip_tfs(file, var->attrs, type, typeformat_offset);
|
||||||
|
case TGT_POINTER:
|
||||||
|
if (last_ptr(type))
|
||||||
{
|
{
|
||||||
case TYPE_STRUCT:
|
size_t start_offset = *typeformat_offset;
|
||||||
if (processed(type)) return type->typestring_offset;
|
int in_attr = is_attr(var->attrs, ATTR_IN);
|
||||||
return write_struct_tfs(file, type, var->name, typeformat_offset);
|
int out_attr = is_attr(var->attrs, ATTR_OUT);
|
||||||
case TYPE_UNION:
|
const type_t *ref = type_pointer_get_ref(type);
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
|
||||||
if (processed(type)) return type->typestring_offset;
|
switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
|
||||||
return write_union_tfs(file, type, typeformat_offset);
|
{
|
||||||
case TYPE_ENUM:
|
/* special case for pointers to base types */
|
||||||
case TYPE_BASIC:
|
case TGT_BASIC:
|
||||||
/* nothing to do */
|
case TGT_ENUM:
|
||||||
return 0;
|
{
|
||||||
default:
|
unsigned char fc;
|
||||||
error("write_typeformatstring_var: Unsupported type %d for variable %s\n",
|
|
||||||
type_get_type(type), var->name);
|
if (type_get_type(ref) == TYPE_ENUM)
|
||||||
|
fc = get_enum_fc(ref);
|
||||||
|
else
|
||||||
|
fc = type_basic_get_fc(ref);
|
||||||
|
|
||||||
|
print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n",
|
||||||
|
get_pointer_fc(type),
|
||||||
|
(!in_attr && out_attr) ? 0x0C : 0x08,
|
||||||
|
string_of_type(get_pointer_fc(type)),
|
||||||
|
(!in_attr && out_attr) ? "[allocated_on_stack] " : "");
|
||||||
|
print_file(file, indent, "0x%02x, /* %s */\n",
|
||||||
|
fc, string_of_type(fc));
|
||||||
|
print_file(file, indent, "0x5c, /* FC_PAD */\n");
|
||||||
|
*typeformat_offset += 4;
|
||||||
|
return start_offset;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset = write_typeformatstring_var(file, indent, func,
|
||||||
|
type_pointer_get_ref(type), var,
|
||||||
|
typeformat_offset);
|
||||||
|
if (file)
|
||||||
|
fprintf(file, "/* %2u */\n", *typeformat_offset);
|
||||||
|
return write_pointer_only_tfs(file, var->attrs, get_pointer_fc(type),
|
||||||
|
!last_ptr(type) ? 0x10 : 0,
|
||||||
|
offset, typeformat_offset);
|
||||||
|
case TGT_INVALID:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (last_ptr(type))
|
error("invalid type %s for var %s\n", type->name, var->name);
|
||||||
{
|
return 0;
|
||||||
unsigned int start_offset = *typeformat_offset;
|
|
||||||
int in_attr = is_attr(var->attrs, ATTR_IN);
|
|
||||||
int out_attr = is_attr(var->attrs, ATTR_OUT);
|
|
||||||
const type_t *ref = type_pointer_get_ref(type);
|
|
||||||
|
|
||||||
if (type_get_type(ref) == TYPE_INTERFACE
|
|
||||||
|| (type_get_type(ref) == TYPE_VOID
|
|
||||||
&& is_attr(var->attrs, ATTR_IIDIS)))
|
|
||||||
{
|
|
||||||
return write_ip_tfs(file, var->attrs, type, typeformat_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* special case for pointers to base types */
|
|
||||||
if (type_get_type(ref) == TYPE_BASIC ||
|
|
||||||
type_get_type(ref) == TYPE_ENUM)
|
|
||||||
{
|
|
||||||
unsigned char fc;
|
|
||||||
|
|
||||||
if (type_get_type(ref) == TYPE_ENUM)
|
|
||||||
fc = get_enum_fc(ref);
|
|
||||||
else
|
|
||||||
fc = type_basic_get_fc(ref);
|
|
||||||
|
|
||||||
print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n",
|
|
||||||
get_pointer_fc(type),
|
|
||||||
(!in_attr && out_attr) ? 0x0C : 0x08,
|
|
||||||
string_of_type(get_pointer_fc(type)),
|
|
||||||
(!in_attr && out_attr) ? "[allocated_on_stack] " : "");
|
|
||||||
print_file(file, indent, "0x%02x, /* %s */\n",
|
|
||||||
fc, string_of_type(fc));
|
|
||||||
print_file(file, indent, "0x5c, /* FC_PAD */\n");
|
|
||||||
*typeformat_offset += 4;
|
|
||||||
return start_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(is_ptr(type));
|
|
||||||
|
|
||||||
offset = write_typeformatstring_var(file, indent, func,
|
|
||||||
type_pointer_get_ref(type), var,
|
|
||||||
typeformat_offset);
|
|
||||||
if (file)
|
|
||||||
fprintf(file, "/* %2u */\n", *typeformat_offset);
|
|
||||||
return write_pointer_only_tfs(file, var->attrs, get_pointer_fc(type),
|
|
||||||
!last_ptr(type) ? 0x10 : 0,
|
|
||||||
offset, typeformat_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
|
static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
|
||||||
@ -2683,39 +2726,31 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
|
|||||||
{
|
{
|
||||||
int retmask = 0;
|
int retmask = 0;
|
||||||
|
|
||||||
if (is_user_type(type))
|
switch (typegen_detect_type(type, attrs, TDT_ALL_TYPES))
|
||||||
{
|
{
|
||||||
|
case TGT_USER_TYPE:
|
||||||
write_user_tfs(file, type, tfsoff);
|
write_user_tfs(file, type, tfsoff);
|
||||||
}
|
break;
|
||||||
else if (is_string_type(attrs, type))
|
case TGT_STRING:
|
||||||
{
|
|
||||||
write_string_tfs(file, attrs, type, name, tfsoff);
|
write_string_tfs(file, attrs, type, name, tfsoff);
|
||||||
}
|
break;
|
||||||
else switch (type_get_type(type))
|
case TGT_IFACE_POINTER:
|
||||||
{
|
write_ip_tfs(file, attrs, type, tfsoff);
|
||||||
case TYPE_POINTER:
|
break;
|
||||||
|
case TGT_POINTER:
|
||||||
{
|
{
|
||||||
type_t *ref = type_pointer_get_ref(type);
|
type_t *ref = type_pointer_get_ref(type);
|
||||||
|
|
||||||
if (type_get_type(ref) == TYPE_INTERFACE
|
if (!processed(ref) && type_get_type(ref) != TYPE_BASIC)
|
||||||
|| (type_get_type(ref) == TYPE_VOID
|
retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff);
|
||||||
&& is_attr(attrs, ATTR_IIDIS)))
|
|
||||||
{
|
|
||||||
write_ip_tfs(file, attrs, type, tfsoff);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!processed(ref) && type_get_type(ref) != TYPE_BASIC)
|
|
||||||
retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff);
|
|
||||||
|
|
||||||
if (write_ptr)
|
if (write_ptr)
|
||||||
write_pointer_tfs(file, type, tfsoff);
|
write_pointer_tfs(file, type, tfsoff);
|
||||||
|
|
||||||
retmask |= 1;
|
retmask |= 1;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_ARRAY:
|
case TGT_ARRAY:
|
||||||
/* conformant arrays and strings are handled specially */
|
/* conformant arrays and strings are handled specially */
|
||||||
if (!type->declarray || !is_conformant_array(type))
|
if (!type->declarray || !is_conformant_array(type))
|
||||||
{
|
{
|
||||||
@ -2724,26 +2759,23 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
|
|||||||
retmask |= 1;
|
retmask |= 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_STRUCT:
|
case TGT_STRUCT:
|
||||||
if (!processed(type))
|
if (!processed(type))
|
||||||
write_struct_tfs(file, type, name, tfsoff);
|
write_struct_tfs(file, type, name, tfsoff);
|
||||||
break;
|
break;
|
||||||
case TYPE_UNION:
|
case TGT_UNION:
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
|
||||||
if (!processed(type))
|
if (!processed(type))
|
||||||
write_union_tfs(file, type, tfsoff);
|
write_union_tfs(file, type, tfsoff);
|
||||||
break;
|
break;
|
||||||
case TYPE_ENUM:
|
case TGT_ENUM:
|
||||||
case TYPE_BASIC:
|
case TGT_BASIC:
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
break;
|
break;
|
||||||
case TYPE_VOID:
|
case TGT_CTXT_HANDLE:
|
||||||
case TYPE_ALIAS:
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
case TYPE_MODULE:
|
case TGT_INVALID:
|
||||||
case TYPE_COCLASS:
|
error("invalid type %s for var %s\n", type->name, name);
|
||||||
case TYPE_FUNCTION:
|
break;
|
||||||
case TYPE_INTERFACE:
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return retmask;
|
return retmask;
|
||||||
@ -2839,95 +2871,108 @@ void write_typeformatstring(FILE *file, const statement_list_t *stmts, type_pred
|
|||||||
static unsigned int get_required_buffer_size_type(
|
static unsigned int get_required_buffer_size_type(
|
||||||
const type_t *type, const char *name, unsigned int *alignment)
|
const type_t *type, const char *name, unsigned int *alignment)
|
||||||
{
|
{
|
||||||
const char *uname;
|
|
||||||
const type_t *utype;
|
|
||||||
|
|
||||||
*alignment = 0;
|
*alignment = 0;
|
||||||
if ((utype = get_user_type(type, &uname)))
|
switch (typegen_detect_type(type, NULL, TDT_IGNORE_STRINGS))
|
||||||
{
|
{
|
||||||
|
case TGT_USER_TYPE:
|
||||||
|
{
|
||||||
|
const char *uname;
|
||||||
|
const type_t *utype = get_user_type(type, &uname);
|
||||||
return get_required_buffer_size_type(utype, uname, alignment);
|
return get_required_buffer_size_type(utype, uname, alignment);
|
||||||
}
|
}
|
||||||
else
|
case TGT_BASIC:
|
||||||
{
|
switch (type_basic_get_fc(type))
|
||||||
switch (type_get_type(type))
|
|
||||||
{
|
{
|
||||||
case TYPE_BASIC:
|
case RPC_FC_BYTE:
|
||||||
switch (type_basic_get_fc(type))
|
case RPC_FC_CHAR:
|
||||||
{
|
case RPC_FC_USMALL:
|
||||||
case RPC_FC_BYTE:
|
case RPC_FC_SMALL:
|
||||||
case RPC_FC_CHAR:
|
*alignment = 4;
|
||||||
case RPC_FC_USMALL:
|
return 1;
|
||||||
case RPC_FC_SMALL:
|
|
||||||
*alignment = 4;
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
case RPC_FC_WCHAR:
|
case RPC_FC_WCHAR:
|
||||||
case RPC_FC_USHORT:
|
case RPC_FC_USHORT:
|
||||||
case RPC_FC_SHORT:
|
case RPC_FC_SHORT:
|
||||||
*alignment = 4;
|
*alignment = 4;
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
case RPC_FC_ULONG:
|
case RPC_FC_ULONG:
|
||||||
case RPC_FC_LONG:
|
case RPC_FC_LONG:
|
||||||
case RPC_FC_FLOAT:
|
case RPC_FC_FLOAT:
|
||||||
case RPC_FC_ERROR_STATUS_T:
|
case RPC_FC_ERROR_STATUS_T:
|
||||||
*alignment = 4;
|
*alignment = 4;
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case RPC_FC_HYPER:
|
case RPC_FC_HYPER:
|
||||||
case RPC_FC_DOUBLE:
|
case RPC_FC_DOUBLE:
|
||||||
*alignment = 8;
|
*alignment = 8;
|
||||||
return 8;
|
return 8;
|
||||||
|
|
||||||
case RPC_FC_IGNORE:
|
case RPC_FC_IGNORE:
|
||||||
case RPC_FC_BIND_PRIMITIVE:
|
case RPC_FC_BIND_PRIMITIVE:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
|
||||||
error("get_required_buffer_size: unknown basic type 0x%02x\n",
|
|
||||||
type_basic_get_fc(type));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_ENUM:
|
|
||||||
switch (get_enum_fc(type))
|
|
||||||
{
|
|
||||||
case RPC_FC_ENUM32:
|
|
||||||
*alignment = 4;
|
|
||||||
return 4;
|
|
||||||
case RPC_FC_ENUM16:
|
|
||||||
*alignment = 4;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_STRUCT:
|
|
||||||
if (get_struct_fc(type) == RPC_FC_STRUCT)
|
|
||||||
{
|
|
||||||
if (!type_struct_get_fields(type)) return 0;
|
|
||||||
return fields_memsize(type_struct_get_fields(type), alignment);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_POINTER:
|
|
||||||
if (get_pointer_fc(type) == RPC_FC_RP)
|
|
||||||
{
|
|
||||||
const type_t *ref = type_pointer_get_ref(type);
|
|
||||||
return (type_get_type(ref) == TYPE_BASIC ||
|
|
||||||
type_get_type(ref) == TYPE_ENUM ||
|
|
||||||
(type_get_type(ref) == TYPE_STRUCT && get_struct_fc(ref) == RPC_FC_STRUCT)) ?
|
|
||||||
get_required_buffer_size_type( ref, name, alignment ) : 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TYPE_ARRAY:
|
|
||||||
return type_array_get_dim(type) *
|
|
||||||
get_required_buffer_size_type(type_array_get_element(type), name, alignment);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
error("get_required_buffer_size: unknown basic type 0x%02x\n",
|
||||||
|
type_basic_get_fc(type));
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TGT_ENUM:
|
||||||
|
switch (get_enum_fc(type))
|
||||||
|
{
|
||||||
|
case RPC_FC_ENUM32:
|
||||||
|
*alignment = 4;
|
||||||
|
return 4;
|
||||||
|
case RPC_FC_ENUM16:
|
||||||
|
*alignment = 4;
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TGT_STRUCT:
|
||||||
|
if (get_struct_fc(type) == RPC_FC_STRUCT)
|
||||||
|
{
|
||||||
|
if (!type_struct_get_fields(type)) return 0;
|
||||||
|
return fields_memsize(type_struct_get_fields(type), alignment);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TGT_POINTER:
|
||||||
|
if (get_pointer_fc(type) == RPC_FC_RP)
|
||||||
|
{
|
||||||
|
const type_t *ref = type_pointer_get_ref(type);
|
||||||
|
switch (typegen_detect_type(ref, NULL, TDT_ALL_TYPES))
|
||||||
|
{
|
||||||
|
case TGT_BASIC:
|
||||||
|
case TGT_ENUM:
|
||||||
|
return get_required_buffer_size_type( ref, name, alignment );
|
||||||
|
case TGT_STRUCT:
|
||||||
|
if (get_struct_fc(ref) == RPC_FC_STRUCT)
|
||||||
|
return get_required_buffer_size_type( ref, name, alignment );
|
||||||
|
break;
|
||||||
|
case TGT_USER_TYPE:
|
||||||
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
|
case TGT_STRING:
|
||||||
|
case TGT_POINTER:
|
||||||
|
case TGT_ARRAY:
|
||||||
|
case TGT_IFACE_POINTER:
|
||||||
|
case TGT_UNION:
|
||||||
|
case TGT_INVALID:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TGT_ARRAY:
|
||||||
|
/* FIXME: depends on pointer type */
|
||||||
|
return type_array_get_dim(type) *
|
||||||
|
get_required_buffer_size_type(type_array_get_element(type), name, alignment);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3252,8 +3297,10 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
|
|
||||||
write_parameter_conf_or_var_exprs(file, indent, local_var_prefix, phase, var);
|
write_parameter_conf_or_var_exprs(file, indent, local_var_prefix, phase, var);
|
||||||
|
|
||||||
if (is_context_handle(type))
|
switch (typegen_detect_type(type, var->attrs, TDT_ALL_TYPES))
|
||||||
{
|
{
|
||||||
|
case TGT_CTXT_HANDLE:
|
||||||
|
case TGT_CTXT_HANDLE_POINTER:
|
||||||
if (phase == PHASE_MARSHAL)
|
if (phase == PHASE_MARSHAL)
|
||||||
{
|
{
|
||||||
if (pass == PASS_IN)
|
if (pass == PASS_IN)
|
||||||
@ -3294,13 +3341,11 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset);
|
print_file(file, indent + 1, "(PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%d]);\n", start_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else if (is_user_type(var->type))
|
case TGT_USER_TYPE:
|
||||||
{
|
|
||||||
print_phase_function(file, indent, "UserMarshal", local_var_prefix, phase, var, start_offset);
|
print_phase_function(file, indent, "UserMarshal", local_var_prefix, phase, var, start_offset);
|
||||||
}
|
break;
|
||||||
else if (is_string_type(var->attrs, var->type))
|
case TGT_STRING:
|
||||||
{
|
|
||||||
if (phase == PHASE_FREE || pass == PASS_RETURN ||
|
if (phase == PHASE_FREE || pass == PASS_RETURN ||
|
||||||
pointer_type != RPC_FC_RP)
|
pointer_type != RPC_FC_RP)
|
||||||
{
|
{
|
||||||
@ -3318,10 +3363,8 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
print_phase_function(file, indent, "ConformantString", local_var_prefix,
|
print_phase_function(file, indent, "ConformantString", local_var_prefix,
|
||||||
phase, var, start_offset);
|
phase, var, start_offset);
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
else switch (type_get_type(type))
|
case TGT_ARRAY:
|
||||||
{
|
|
||||||
case TYPE_ARRAY:
|
|
||||||
{
|
{
|
||||||
unsigned char tc = get_array_fc(type);
|
unsigned char tc = get_array_fc(type);
|
||||||
const char *array_type = "FixedArray";
|
const char *array_type = "FixedArray";
|
||||||
@ -3365,11 +3408,11 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_BASIC:
|
case TGT_BASIC:
|
||||||
if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
|
if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
|
||||||
print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
|
print_phase_basetype(file, indent, local_var_prefix, phase, pass, var, var->name);
|
||||||
break;
|
break;
|
||||||
case TYPE_ENUM:
|
case TGT_ENUM:
|
||||||
if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
|
if (phase == PHASE_MARSHAL || phase == PHASE_UNMARSHAL)
|
||||||
{
|
{
|
||||||
if (phase == PHASE_MARSHAL)
|
if (phase == PHASE_MARSHAL)
|
||||||
@ -3383,7 +3426,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
print_file(file, indent+1, "0x%02x /* %s */);\n", get_enum_fc(type), string_of_type(get_enum_fc(type)));
|
print_file(file, indent+1, "0x%02x /* %s */);\n", get_enum_fc(type), string_of_type(get_enum_fc(type)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_STRUCT:
|
case TGT_STRUCT:
|
||||||
switch (get_struct_fc(type))
|
switch (get_struct_fc(type))
|
||||||
{
|
{
|
||||||
case RPC_FC_STRUCT:
|
case RPC_FC_STRUCT:
|
||||||
@ -3407,8 +3450,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, get_struct_fc(type));
|
error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, get_struct_fc(type));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_UNION:
|
case TGT_UNION:
|
||||||
case TYPE_ENCAPSULATED_UNION:
|
|
||||||
{
|
{
|
||||||
const char *union_type = NULL;
|
const char *union_type = NULL;
|
||||||
|
|
||||||
@ -3421,7 +3463,7 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
phase, var, start_offset);
|
phase, var, start_offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_POINTER:
|
case TGT_POINTER:
|
||||||
{
|
{
|
||||||
const type_t *ref = type_pointer_get_ref(type);
|
const type_t *ref = type_pointer_get_ref(type);
|
||||||
if (get_pointer_fc(type) == RPC_FC_RP && !is_user_type(ref)) switch (type_get_type(ref))
|
if (get_pointer_fc(type) == RPC_FC_RP && !is_user_type(ref)) switch (type_get_type(ref))
|
||||||
@ -3503,29 +3545,23 @@ static void write_remoting_arg(FILE *file, int indent, const var_t *func, const
|
|||||||
case TYPE_ARRAY:
|
case TYPE_ARRAY:
|
||||||
print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
|
print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
|
||||||
break;
|
break;
|
||||||
case TYPE_INTERFACE:
|
|
||||||
print_phase_function(file, indent, "InterfacePointer", local_var_prefix, phase, var, start_offset);
|
|
||||||
break;
|
|
||||||
case TYPE_VOID:
|
case TYPE_VOID:
|
||||||
case TYPE_ALIAS:
|
case TYPE_ALIAS:
|
||||||
case TYPE_MODULE:
|
case TYPE_MODULE:
|
||||||
case TYPE_COCLASS:
|
case TYPE_COCLASS:
|
||||||
case TYPE_FUNCTION:
|
case TYPE_FUNCTION:
|
||||||
|
case TYPE_INTERFACE:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (type_get_type(ref) == TYPE_INTERFACE)
|
|
||||||
print_phase_function(file, indent, "InterfacePointer", local_var_prefix, phase, var, start_offset);
|
|
||||||
else
|
else
|
||||||
print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
|
print_phase_function(file, indent, "Pointer", local_var_prefix, phase, var, start_offset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TYPE_VOID:
|
case TGT_IFACE_POINTER:
|
||||||
case TYPE_ALIAS:
|
print_phase_function(file, indent, "InterfacePointer", local_var_prefix, phase, var, start_offset);
|
||||||
case TYPE_MODULE:
|
break;
|
||||||
case TYPE_COCLASS:
|
case TGT_INVALID:
|
||||||
case TYPE_FUNCTION:
|
|
||||||
case TYPE_INTERFACE:
|
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,28 @@ enum remoting_phase
|
|||||||
PHASE_FREE
|
PHASE_FREE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum typegen_detect_flags
|
||||||
|
{
|
||||||
|
TDT_ALL_TYPES = 1 << 0,
|
||||||
|
TDT_IGNORE_STRINGS = 1 << 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum typegen_type
|
||||||
|
{
|
||||||
|
TGT_INVALID,
|
||||||
|
TGT_USER_TYPE,
|
||||||
|
TGT_CTXT_HANDLE,
|
||||||
|
TGT_CTXT_HANDLE_POINTER,
|
||||||
|
TGT_STRING,
|
||||||
|
TGT_POINTER,
|
||||||
|
TGT_ARRAY,
|
||||||
|
TGT_IFACE_POINTER,
|
||||||
|
TGT_BASIC,
|
||||||
|
TGT_ENUM,
|
||||||
|
TGT_STRUCT,
|
||||||
|
TGT_UNION,
|
||||||
|
};
|
||||||
|
|
||||||
typedef int (*type_pred_t)(const type_t *);
|
typedef int (*type_pred_t)(const type_t *);
|
||||||
|
|
||||||
void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred);
|
void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred);
|
||||||
@ -68,3 +90,4 @@ void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_s
|
|||||||
void write_full_pointer_free(FILE *file, int indent, const var_t *func);
|
void write_full_pointer_free(FILE *file, int indent, const var_t *func);
|
||||||
unsigned char get_pointer_fc(const type_t *type);
|
unsigned char get_pointer_fc(const type_t *type);
|
||||||
unsigned char get_struct_fc(const type_t *type);
|
unsigned char get_struct_fc(const type_t *type);
|
||||||
|
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user