Commit 2c6e611c authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

widl: Add typegen_detect_type and use it.

Add typegen_detect_type for detecting types useful during client/server/proxy code generation.
parent af080072
......@@ -2342,8 +2342,7 @@ static void check_field_common(const type_t *container_type,
const char *container_name, const var_t *arg)
{
type_t *type = arg->type;
int is_wire_marshal = 0;
int is_context_handle = 0;
int more_to_do;
const char *container_type_name = NULL;
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 */
for (;;)
do
{
if (is_attr(type->attrs, ATTR_WIREMARSHAL))
more_to_do = FALSE;
switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
{
is_wire_marshal = 1;
case TGT_STRUCT:
case TGT_UNION:
check_remoting_fields(arg, type);
break;
}
if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
{
is_context_handle = 1;
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;
}
if (type_is_alias(type))
type = type_alias_get_aliasee(type);
else if (is_ptr(type))
case TGT_POINTER:
type = type_pointer_get_ref(type);
else if (is_array(type))
more_to_do = TRUE;
break;
case TGT_ARRAY:
type = type_array_get_element(type);
else
more_to_do = TRUE;
break;
}
if (type_get_type(type) == TYPE_VOID && !is_attr(arg->attrs, ATTR_IIDIS) && !is_wire_marshal && !is_context_handle)
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)
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n", arg->name, container_type_name, container_name);
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);
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)
......@@ -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 )
{
int ptr_level = 0;
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 */
if (is_attr(arg->attrs, ATTR_OUT))
{
if (!is_array(type))
switch (typegen_detect_type(type, arg->attrs, TDT_ALL_TYPES))
{
if (!ptr_level)
error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
if (type_get_type(type) == TYPE_INTERFACE && ptr_level == 1)
error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
case TGT_BASIC:
case TGT_ENUM:
case TGT_STRUCT:
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)
{
const type_t *type = v->type;
/* 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;
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;
}
return (get_pointer_fc(type) == RPC_FC_RP);
}
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;
}
switch (type_get_type(type))
switch (typegen_detect_type(type, arg->attrs, TDT_IGNORE_STRINGS))
{
case TYPE_ENUM:
case TYPE_BASIC:
case TGT_ENUM:
case TGT_BASIC:
break;
case TYPE_STRUCT:
case TGT_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;
case TYPE_POINTER:
case TYPE_INTERFACE:
if (type_get_type(type) == TYPE_INTERFACE || get_pointer_fc(type) == RPC_FC_FP)
case TGT_IFACE_POINTER:
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" );
}
/* 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, ");
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
fprintf(proxy, "(void*)%s );\n", arg->name );
......
......@@ -36,6 +36,28 @@ enum remoting_phase
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 *);
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);
unsigned char get_pointer_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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment