widl: Support WinRT delegate type.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Jacek Caban<jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6991d7befa
commit
2326d7226d
|
@ -466,6 +466,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
|
|||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
case TYPE_DELEGATE:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case TYPE_ALIAS:
|
||||
|
|
|
@ -470,6 +470,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
|
|||
case TYPE_RUNTIMECLASS:
|
||||
fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type));
|
||||
break;
|
||||
case TYPE_DELEGATE:
|
||||
fprintf(h, "%s", type_get_name(type_delegate_get_iface(t), name_type));
|
||||
break;
|
||||
case TYPE_VOID:
|
||||
fprintf(h, "void");
|
||||
break;
|
||||
|
@ -555,6 +558,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
|
|||
case TYPE_COCLASS:
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
|
@ -974,7 +978,7 @@ int has_out_arg_or_return(const var_t *func)
|
|||
int is_object(const type_t *iface)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (type_is_defined(iface) && type_iface_get_inherit(iface))
|
||||
if (type_is_defined(iface) && (type_get_type(iface) == TYPE_DELEGATE || type_iface_get_inherit(iface)))
|
||||
return 1;
|
||||
if (iface->attrs) LIST_FOR_EACH_ENTRY( attr, iface->attrs, const attr_t, entry )
|
||||
if (attr->type == ATTR_OBJECT || attr->type == ATTR_ODL) return 1;
|
||||
|
@ -1799,9 +1803,10 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
|
|||
switch (stmt->type)
|
||||
{
|
||||
case STMT_TYPE:
|
||||
if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
|
||||
if (type_get_type(stmt->u.type) == TYPE_INTERFACE || type_get_type(stmt->u.type) == TYPE_DELEGATE)
|
||||
{
|
||||
type_t *iface = stmt->u.type;
|
||||
if (type_get_type(iface) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
|
||||
if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
|
||||
{
|
||||
write_forward(header, iface);
|
||||
|
@ -1841,10 +1846,11 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
|
|||
switch (stmt->type)
|
||||
{
|
||||
case STMT_TYPE:
|
||||
if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
|
||||
if (type_get_type(stmt->u.type) == TYPE_INTERFACE || type_get_type(stmt->u.type) == TYPE_DELEGATE)
|
||||
{
|
||||
type_t *iface = stmt->u.type;
|
||||
type_t *async_iface = type_iface_get_async_iface(iface);
|
||||
type_t *iface = stmt->u.type, *async_iface;
|
||||
if (type_get_type(stmt->u.type) == TYPE_DELEGATE) iface = type_delegate_get_iface(iface);
|
||||
async_iface = type_iface_get_async_iface(iface);
|
||||
if (is_object(iface)) is_object_interface++;
|
||||
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
|
||||
{
|
||||
|
|
|
@ -278,6 +278,7 @@ static const struct keyword keywords[] = {
|
|||
{"cpp_quote", tCPPQUOTE, 0},
|
||||
{"declare", tDECLARE, 1},
|
||||
{"default", tDEFAULT, 0},
|
||||
{"delegate", tDELEGATE, 1},
|
||||
{"dispinterface", tDISPINTERFACE, 0},
|
||||
{"double", tDOUBLE, 0},
|
||||
{"enum", tENUM, 0},
|
||||
|
|
|
@ -106,6 +106,7 @@ static statement_t *make_statement_module(type_t *type);
|
|||
static statement_t *make_statement_typedef(var_list_t *names, int declonly);
|
||||
static statement_t *make_statement_import(const char *str);
|
||||
static statement_t *make_statement_parameterized_type(type_t *type, typeref_list_t *params);
|
||||
static statement_t *make_statement_delegate(type_t *ret, var_list_t *args);
|
||||
static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
|
||||
static statement_list_t *append_statements(statement_list_t *, statement_list_t *);
|
||||
static attr_list_t *append_attribs(attr_list_t *, attr_list_t *);
|
||||
|
@ -180,6 +181,7 @@ static typelib_t *current_typelib;
|
|||
%token tCUSTOM
|
||||
%token tDECLARE
|
||||
%token tDECODE tDEFAULT tDEFAULTBIND
|
||||
%token tDELEGATE
|
||||
%token tDEFAULTCOLLELEM
|
||||
%token tDEFAULTVALUE
|
||||
%token tDEFAULTVTABLE
|
||||
|
@ -278,6 +280,7 @@ static typelib_t *current_typelib;
|
|||
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
|
||||
%type <expr> contract_req
|
||||
%type <expr> static_attr
|
||||
%type <type> delegatedef
|
||||
%type <stgclass> storage_cls_spec
|
||||
%type <type_qualifier> type_qualifier m_type_qual_list
|
||||
%type <function_specifier> function_specifier
|
||||
|
@ -384,6 +387,7 @@ gbl_statements: { $$ = NULL; }
|
|||
| gbl_statements interface ';' { $$ = append_statement($1, make_statement_reference($2)); }
|
||||
| gbl_statements dispinterface ';' { $$ = append_statement($1, make_statement_reference($2)); }
|
||||
| gbl_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| gbl_statements delegatedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| gbl_statements coclass ';' { $$ = $1;
|
||||
reg_type($2, $2->name, current_namespace, 0);
|
||||
}
|
||||
|
@ -408,6 +412,7 @@ imp_statements: { $$ = NULL; }
|
|||
| imp_statements namespacedef '{' { push_namespace($2); } imp_statements '}'
|
||||
{ pop_namespace($2); $$ = append_statements($1, $5); }
|
||||
| imp_statements interfacedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| imp_statements delegatedef { $$ = append_statement($1, make_statement_type_decl($2)); }
|
||||
| imp_statements coclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
|
||||
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
|
||||
reg_type($2, $2->name, current_namespace, 0);
|
||||
|
@ -1029,6 +1034,12 @@ interface:
|
|||
{ $$ = type_parameterized_interface_declare($2, current_namespace, $5); }
|
||||
;
|
||||
|
||||
delegatedef: m_attributes tDELEGATE type ident '(' m_args ')' semicolon_opt
|
||||
{ $$ = type_delegate_declare($4->name, current_namespace);
|
||||
$$ = type_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $6)));
|
||||
}
|
||||
;
|
||||
|
||||
required_types:
|
||||
qualified_type { $$ = append_typeref(NULL, make_typeref($1)); }
|
||||
| parameterized_type { $$ = append_typeref(NULL, make_typeref($1)); }
|
||||
|
@ -2663,6 +2674,7 @@ static int is_allowed_conf_type(const type_t *type)
|
|||
case TYPE_INTERFACE:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
return FALSE;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
|
@ -3299,6 +3311,14 @@ static statement_t *make_statement_parameterized_type(type_t *type, typeref_list
|
|||
return stmt;
|
||||
}
|
||||
|
||||
static statement_t *make_statement_delegate(type_t *ret, var_list_t *args)
|
||||
{
|
||||
declarator_t *decl = make_declarator(make_var(xstrdup("Invoke")));
|
||||
decl_spec_t *spec = make_decl_spec(ret, NULL, NULL, STG_NONE, 0, 0);
|
||||
append_chain_type(decl, type_new_function(args), 0);
|
||||
return make_statement_declaration(declare_var(NULL, spec, decl, FALSE));
|
||||
}
|
||||
|
||||
static statement_list_t *append_statements(statement_list_t *l1, statement_list_t *l2)
|
||||
{
|
||||
if (!l2) return l1;
|
||||
|
|
|
@ -354,6 +354,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
|||
case TYPE_POINTER:
|
||||
if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
|
||||
type_get_type(type_pointer_get_ref_type(type)) == TYPE_RUNTIMECLASS ||
|
||||
type_get_type(type_pointer_get_ref_type(type)) == TYPE_DELEGATE ||
|
||||
(type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
|
||||
return TGT_IFACE_POINTER;
|
||||
else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
|
||||
|
@ -375,6 +376,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
|
|||
case TYPE_ALIAS:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
break;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
|
@ -1978,6 +1980,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
|
|||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
case TYPE_DELEGATE:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
|
@ -2083,6 +2086,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
|
|||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
case TYPE_PARAMETER:
|
||||
case TYPE_DELEGATE:
|
||||
/* these types should not be encountered here due to language
|
||||
* restrictions (interface, void, coclass, module), logical
|
||||
* restrictions (alias - due to type_get_type call above) or
|
||||
|
|
|
@ -219,6 +219,7 @@ unsigned short get_type_vt(type_t *t)
|
|||
case TYPE_UNION:
|
||||
case TYPE_ENCAPSULATED_UNION:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
return VT_USERDEFINED;
|
||||
|
||||
case TYPE_VOID:
|
||||
|
|
|
@ -664,6 +664,54 @@ type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs)
|
|||
return apicontract;
|
||||
}
|
||||
|
||||
static void compute_delegate_iface_names(type_t *delegate)
|
||||
{
|
||||
type_t *iface = delegate->details.delegate.iface;
|
||||
iface->namespace = delegate->namespace;
|
||||
iface->name = strmake("I%s", delegate->name);
|
||||
iface->c_name = format_namespace(delegate->namespace, "__x_", "_C", iface->name, use_abi_namespace ? "ABI" : NULL);
|
||||
}
|
||||
|
||||
type_t *type_delegate_declare(char *name, struct namespace *namespace)
|
||||
{
|
||||
type_t *type = get_type(TYPE_DELEGATE, name, NULL, 0);
|
||||
if (type_get_type_detect_alias(type) != TYPE_DELEGATE)
|
||||
error_loc("delegate %s previously not declared a delegate at %s:%d\n",
|
||||
type->name, type->loc_info.input_name, type->loc_info.line_number);
|
||||
return type;
|
||||
}
|
||||
|
||||
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_list_t *stmts)
|
||||
{
|
||||
type_t *iface;
|
||||
|
||||
if (delegate->defined)
|
||||
error_loc("delegate %s already defined at %s:%d\n",
|
||||
delegate->name, delegate->loc_info.input_name, delegate->loc_info.line_number);
|
||||
|
||||
delegate->attrs = check_interface_attrs(delegate->name, attrs);
|
||||
|
||||
iface = make_type(TYPE_INTERFACE);
|
||||
iface->attrs = delegate->attrs;
|
||||
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
|
||||
iface->details.iface->disp_props = NULL;
|
||||
iface->details.iface->disp_methods = NULL;
|
||||
iface->details.iface->stmts = stmts;
|
||||
iface->details.iface->inherit = find_type("IUnknown", NULL, 0);
|
||||
if (!iface->details.iface->inherit) error_loc("IUnknown is undefined\n");
|
||||
iface->details.iface->disp_inherit = NULL;
|
||||
iface->details.iface->async_iface = NULL;
|
||||
iface->details.iface->requires = NULL;
|
||||
iface->defined = TRUE;
|
||||
compute_method_indexes(iface);
|
||||
|
||||
delegate->details.delegate.iface = iface;
|
||||
delegate->defined = TRUE;
|
||||
compute_delegate_iface_names(delegate);
|
||||
|
||||
return delegate;
|
||||
}
|
||||
|
||||
type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, typeref_list_t *params)
|
||||
{
|
||||
type_t *type = get_type(TYPE_PARAMETERIZED_TYPE, name, namespace, 0);
|
||||
|
@ -821,6 +869,7 @@ static type_t *replace_type_parameters_in_type(type_t *type, typeref_list_t *ori
|
|||
case TYPE_BITFIELD:
|
||||
case TYPE_INTERFACE:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
return type;
|
||||
case TYPE_PARAMETER:
|
||||
if (!orig || !repl) return NULL;
|
||||
|
|
|
@ -64,6 +64,8 @@ type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, typeref_list_t
|
|||
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, typeref_list_t *ifaces);
|
||||
type_t *type_apicontract_declare(char *name, struct namespace *namespace);
|
||||
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs);
|
||||
type_t *type_delegate_declare(char *name, struct namespace *namespace);
|
||||
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_list_t *stmts);
|
||||
type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, typeref_list_t *params);
|
||||
type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, typeref_list_t *requires);
|
||||
type_t *type_parameterized_type_specialize_partial(type_t *type, typeref_list_t *params);
|
||||
|
@ -254,6 +256,7 @@ static inline int type_is_complete(const type_t *type)
|
|||
case TYPE_ARRAY:
|
||||
case TYPE_BITFIELD:
|
||||
case TYPE_RUNTIMECLASS:
|
||||
case TYPE_DELEGATE:
|
||||
return TRUE;
|
||||
case TYPE_APICONTRACT:
|
||||
case TYPE_PARAMETERIZED_TYPE:
|
||||
|
@ -376,6 +379,13 @@ static inline type_t *type_runtimeclass_get_default_iface(const type_t *type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline type_t *type_delegate_get_iface(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
assert(type_get_type(type) == TYPE_DELEGATE);
|
||||
return type->details.delegate.iface;
|
||||
}
|
||||
|
||||
static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
|
||||
{
|
||||
type = type_get_real_type(type);
|
||||
|
|
|
@ -441,6 +441,11 @@ struct parameterized_details
|
|||
typeref_list_t *params;
|
||||
};
|
||||
|
||||
struct delegate_details
|
||||
{
|
||||
type_t *iface;
|
||||
};
|
||||
|
||||
#define HASHMAX 64
|
||||
|
||||
struct namespace {
|
||||
|
@ -471,6 +476,7 @@ enum type_type
|
|||
TYPE_RUNTIMECLASS,
|
||||
TYPE_PARAMETERIZED_TYPE,
|
||||
TYPE_PARAMETER,
|
||||
TYPE_DELEGATE,
|
||||
};
|
||||
|
||||
struct _type_t {
|
||||
|
@ -493,6 +499,7 @@ struct _type_t {
|
|||
struct alias_details alias;
|
||||
struct runtimeclass_details runtimeclass;
|
||||
struct parameterized_details parameterized;
|
||||
struct delegate_details delegate;
|
||||
} details;
|
||||
const char *c_name;
|
||||
unsigned int typestring_offset;
|
||||
|
|
Loading…
Reference in New Issue