Rebase against dd417540bb3afb3aa5a04a007eea9a7ee347655b.

This commit is contained in:
Zebediah Figura
2021-02-04 17:28:33 -06:00
parent cfe1b94e0f
commit a2f82c5c85
45 changed files with 2228 additions and 1319 deletions

View File

@@ -0,0 +1,162 @@
From 72fb994d9750998fde2d8ecbb9bd98983aeb66f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 10:35:39 +0100
Subject: [PATCH] widl: Factor and cleanup interface type declaration and
definition.
---
tools/widl/parser.y | 34 ++++++++++------------------------
tools/widl/typetree.c | 19 ++++++++++++++++++-
tools/widl/typetree.h | 4 +++-
3 files changed, 31 insertions(+), 26 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 1505e3e88a0..44716deb5b6 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -87,7 +87,6 @@ static void push_lookup_namespace(const char *name);
static void check_arg_attrs(const var_t *arg);
static void check_statements(const statement_list_t *stmts, int is_inside_library);
static void check_all_user_types(const statement_list_t *stmts);
-static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
static attr_list_t *check_enum_attrs(attr_list_t *attrs);
@@ -281,7 +280,6 @@ static typelib_t *current_typelib;
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
%type <expr> contract_req
-%type <type> interfacehdr
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
%type <function_specifier> function_specifier
@@ -971,31 +969,20 @@ inherit: { $$ = NULL; }
| ':' qualified_type { $$ = $2; }
;
-interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
- | tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
+interface:
+ tINTERFACE aIDENTIFIER { $$ = type_interface_declare($2, current_namespace); }
+ | tINTERFACE aKNOWNTYPE { $$ = type_interface_declare($2, current_namespace); }
;
-interfacehdr: attributes interface { $$ = $2;
- check_def($2);
- $2->attrs = check_iface_attrs($2->name, $1);
- $2->defined = TRUE;
- }
- ;
-
-interfacedef: interfacehdr inherit
- '{' int_statements '}' semicolon_opt { $$ = $1;
- if($$ == $2)
- error_loc("Interface can't inherit from itself\n");
- type_interface_define($$, $2, $4);
+interfacedef: attributes interface inherit
+ '{' int_statements '}' semicolon_opt { $$ = type_interface_define($2, $1, $3, $5);
check_async_uuid($$);
}
/* MIDL is able to import the definition of a base class from inside the
* definition of a derived class, I'll try to support it with this rule */
- | interfacehdr ':' aIDENTIFIER
+ | attributes interface ':' aIDENTIFIER
'{' import int_statements '}'
- semicolon_opt { $$ = $1;
- type_interface_define($$, find_type_or_error($3), $6);
- }
+ semicolon_opt { $$ = type_interface_define($2, $1, find_type_or_error($4), $7); }
| dispinterfacedef semicolon_opt { $$ = $1; }
;
@@ -2340,7 +2327,7 @@ const char *get_attr_display_name(enum attr_type type)
return allowed_attr[type].display_name;
}
-static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
+attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs)
{
const attr_t *attr;
if (!attrs) return attrs;
@@ -2978,8 +2965,7 @@ static void check_async_uuid(type_t *iface)
if (!inherit)
error_loc("async_uuid applied to an interface with incompatible parent\n");
- async_iface = get_type(TYPE_INTERFACE, strmake("Async%s", iface->name), iface->namespace, 0);
- async_iface->attrs = map_attrs(iface->attrs, async_iface_attrs);
+ async_iface = type_interface_declare(strmake("Async%s", iface->name), iface->namespace);
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
{
@@ -3010,7 +2996,7 @@ static void check_async_uuid(type_t *iface)
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
- type_interface_define(async_iface, inherit, stmts);
+ type_interface_define(async_iface, map_attrs(iface->attrs, async_iface_attrs), inherit, stmts);
iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface;
}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 825348ddef4..84be75fa3b7 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -442,8 +442,24 @@ static unsigned int compute_method_indexes(type_t *iface)
return idx;
}
-void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
+type_t *type_interface_declare(char *name, struct namespace *namespace)
{
+ type_t *type = get_type(TYPE_INTERFACE, name, namespace, 0);
+ if (type_get_type_detect_alias(type) != TYPE_INTERFACE)
+ error_loc("interface %s previously not declared an interface at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ return type;
+}
+
+type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts)
+{
+ if (iface->defined)
+ error_loc("interface %s already defined at %s:%d\n",
+ iface->name, iface->loc_info.input_name, iface->loc_info.line_number);
+ if (iface == inherit)
+ error_loc("interface %s can't inherit from itself\n",
+ iface->name);
+ iface->attrs = check_interface_attrs(iface->name, attrs);
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->details.iface->disp_props = NULL;
iface->details.iface->disp_methods = NULL;
@@ -453,6 +469,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
iface->details.iface->async_iface = NULL;
iface->defined = TRUE;
compute_method_indexes(iface);
+ return iface;
}
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 8a8e1c529ac..7b67f3b996a 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -30,6 +30,7 @@ enum name_type {
};
attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
+attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs);
type_t *type_new_function(var_list_t *args);
@@ -48,7 +49,8 @@ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_runtimeclass_declare(char *name, struct namespace *namespace);
-void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
+type_t *type_interface_declare(char *name, struct namespace *namespace);
+type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts);
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts);
--
2.20.1

View File

@@ -0,0 +1,182 @@
From ae71cd3e9512f1b96ef79eb76507046128e94f6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 10:34:24 +0100
Subject: [PATCH] widl: Factor and cleanup dispinterface type declaration and
definition.
---
tools/widl/parser.y | 36 +++++++++++++-----------------------
tools/widl/typetree.c | 23 +++++++++++++++++++++--
tools/widl/typetree.h | 6 ++++--
3 files changed, 38 insertions(+), 27 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 44716deb5b6..349e4730d96 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -95,7 +95,6 @@ static attr_list_t *check_struct_attrs(attr_list_t *attrs);
static attr_list_t *check_union_attrs(attr_list_t *attrs);
static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
-static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
const char *get_attr_display_name(enum attr_type type);
@@ -276,6 +275,7 @@ static typelib_t *current_typelib;
%type <attr> attribute acf_attribute
%type <attr_list> m_attributes attributes attrib_list
%type <attr_list> acf_attributes acf_attribute_list
+%type <attr_list> dispattributes
%type <str_list> str_list
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
@@ -286,7 +286,7 @@ static typelib_t *current_typelib;
%type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
%type <type> inherit interface interfacedef
%type <type> interfaceref
-%type <type> dispinterface dispinterfacehdr dispinterfacedef
+%type <type> dispinterface dispinterfacedef
%type <type> module modulehdr moduledef
%type <str> namespacedef
%type <type> base_type int_std
@@ -932,17 +932,12 @@ class_interface:
m_attributes interfaceref ';' { $$ = make_ifref($2); $$->attrs = $1; }
;
-dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
- | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
+dispinterface:
+ tDISPINTERFACE aIDENTIFIER { $$ = type_dispinterface_declare($2); }
+ | tDISPINTERFACE aKNOWNTYPE { $$ = type_dispinterface_declare($2); }
;
-dispinterfacehdr: attributes dispinterface { attr_t *attrs;
- $$ = $2;
- check_def($$);
- attrs = make_attr(ATTR_DISPINTERFACE);
- $$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
- $$->defined = TRUE;
- }
+dispattributes: attributes { $$ = append_attr($1, make_attr(ATTR_DISPINTERFACE)); }
;
dispint_props: tPROPERTIES ':' { $$ = NULL; }
@@ -953,16 +948,11 @@ dispint_meths: tMETHODS ':' { $$ = NULL; }
| dispint_meths funcdef ';' { $$ = append_var( $1, $2 ); }
;
-dispinterfacedef: dispinterfacehdr '{'
- dispint_props
- dispint_meths
- '}' { $$ = $1;
- type_dispinterface_define($$, $3, $4);
- }
- | dispinterfacehdr
- '{' interface ';' '}' { $$ = $1;
- type_dispinterface_define_from_iface($$, $3);
- }
+dispinterfacedef:
+ dispattributes dispinterface '{' dispint_props dispint_meths '}'
+ { $$ = type_dispinterface_define($2, $1, $4, $5); }
+ | dispattributes dispinterface '{' interface ';' '}'
+ { $$ = type_dispinterface_define_from_iface($2, $1, $4); }
;
inherit: { $$ = NULL; }
@@ -2214,7 +2204,7 @@ struct allowed_attr allowed_attr[] =
/* ATTR_DEFAULTVALUE */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "defaultvalue" },
/* ATTR_DEFAULTVTABLE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, "defaultvtable" },
/* ATTR_DISABLECONSISTENCYCHECK */{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "disable_consistency_check" },
- /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
+ /* ATTR_DISPINTERFACE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, NULL },
/* ATTR_DISPLAYBIND */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
/* ATTR_DLLNAME */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "dllname" },
/* ATTR_DUAL */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
@@ -2471,7 +2461,7 @@ static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs)
return attrs;
}
-static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
+attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
{
const attr_t *attr;
if (!attrs) return attrs;
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 84be75fa3b7..81eaba5556b 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -472,8 +472,21 @@ type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit
return iface;
}
-void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods)
+type_t *type_dispinterface_declare(char *name)
{
+ type_t *type = get_type(TYPE_INTERFACE, name, NULL, 0);
+ if (type_get_type_detect_alias(type) != TYPE_INTERFACE)
+ error_loc("dispinterface %s previously not declared a dispinterface at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ return type;
+}
+
+type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t *props, var_list_t *methods)
+{
+ if (iface->defined)
+ error_loc("dispinterface %s already defined at %s:%d\n",
+ iface->name, iface->loc_info.input_name, iface->loc_info.line_number);
+ iface->attrs = check_dispiface_attrs(iface->name, attrs);
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->details.iface->disp_props = props;
iface->details.iface->disp_methods = methods;
@@ -484,10 +497,15 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
iface->details.iface->async_iface = NULL;
iface->defined = TRUE;
compute_method_indexes(iface);
+ return iface;
}
-void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
+type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *attrs, type_t *iface)
{
+ if (dispiface->defined)
+ error_loc("dispinterface %s already defined at %s:%d\n",
+ dispiface->name, dispiface->loc_info.input_name, dispiface->loc_info.line_number);
+ dispiface->attrs = check_dispiface_attrs(dispiface->name, attrs);
dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
dispiface->details.iface->disp_props = NULL;
dispiface->details.iface->disp_methods = NULL;
@@ -498,6 +516,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
dispiface->details.iface->async_iface = NULL;
dispiface->defined = TRUE;
compute_method_indexes(dispiface);
+ return dispiface;
}
void type_module_define(type_t *module, statement_list_t *stmts)
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 7b67f3b996a..280d2e722cf 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -30,6 +30,7 @@ enum name_type {
};
attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
+attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs);
@@ -51,8 +52,9 @@ type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_runtimeclass_declare(char *name, struct namespace *namespace);
type_t *type_interface_declare(char *name, struct namespace *namespace);
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts);
-void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
-void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
+type_t *type_dispinterface_declare(char *name);
+type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t *props, var_list_t *methods);
+type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *attrs, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *ifaces);
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_list_t *ifaces);
--
2.20.1

View File

@@ -0,0 +1,154 @@
From 623643c78b618ae83aaebaaf16988d8765bf5eff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 10:56:18 +0100
Subject: [PATCH] widl: Factor and cleanup apicontract type declaration and
definition.
And remove unused check_def helper.
---
tools/widl/parser.y | 35 +++++++++++++++--------------------
tools/widl/typetree.c | 19 +++++++++++++++++++
tools/widl/typetree.h | 3 +++
3 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 349e4730d96..8c805e481f8 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -96,10 +96,8 @@ static attr_list_t *check_union_attrs(attr_list_t *attrs);
static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
-static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
const char *get_attr_display_name(enum attr_type type);
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
-static void check_def(const type_t *t);
static void check_async_uuid(type_t *iface);
@@ -305,7 +303,7 @@ static typelib_t *current_typelib;
%type <declarator_list> declarator_list struct_declarator_list
%type <type> coclass coclassdef
%type <type> runtimeclass runtimeclass_def
-%type <type> apicontract
+%type <type> apicontract apicontract_def
%type <num> contract_ver
%type <num> pointer_type threading_type marshaling_behavior version
%type <str> libraryhdr callconv cppquote importlib import t_ident
@@ -364,8 +362,9 @@ gbl_statements: { $$ = NULL; }
| gbl_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, current_namespace, 0);
}
- | gbl_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
- reg_type($2, $2->name, current_namespace, 0); }
+ | gbl_statements apicontract ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
+ | gbl_statements apicontract_def { $$ = append_statement($1, make_statement_type_decl($2));
+ reg_type($2, $2->name, current_namespace, 0); }
| gbl_statements runtimeclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
| gbl_statements runtimeclass_def { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, current_namespace, 0); }
@@ -384,8 +383,9 @@ imp_statements: { $$ = NULL; }
| imp_statements coclassdef { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, current_namespace, 0);
}
- | imp_statements apicontract ';' { $$ = append_statement($1, make_statement_type_decl($2));
- reg_type($2, $2->name, current_namespace, 0); }
+ | imp_statements apicontract ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
+ | imp_statements apicontract_def { $$ = append_statement($1, make_statement_type_decl($2));
+ reg_type($2, $2->name, current_namespace, 0); }
| imp_statements runtimeclass ';' { $$ = $1; reg_type($2, $2->name, current_namespace, 0); }
| imp_statements runtimeclass_def { $$ = append_statement($1, make_statement_type_decl($2));
reg_type($2, $2->name, current_namespace, 0); }
@@ -913,11 +913,13 @@ runtimeclass_def: attributes runtimeclass '{' class_interfaces '}' semicolon_opt
{ $$ = type_runtimeclass_define($2, $1, $4); }
;
-apicontract: attributes tAPICONTRACT aIDENTIFIER '{' '}'
- { $$ = get_type(TYPE_APICONTRACT, $3, current_namespace, 0);
- check_def($$);
- $$->attrs = check_apicontract_attrs($$->name, $1);
- }
+apicontract:
+ tAPICONTRACT aIDENTIFIER { $$ = type_apicontract_declare($2, current_namespace); }
+ | tAPICONTRACT aKNOWNTYPE { $$ = type_apicontract_declare($2, current_namespace); }
+ ;
+
+apicontract_def: attributes apicontract '{' '}' semicolon_opt
+ { $$ = type_apicontract_define($2, $1); }
;
namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; }
@@ -2511,7 +2513,7 @@ attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs)
return attrs;
}
-static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
+attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs)
{
const attr_t *attr;
if (!attrs) return attrs;
@@ -3205,10 +3207,3 @@ void init_loc_info(loc_info_t *i)
i->line_number = line_number;
i->near_text = parser_text;
}
-
-static void check_def(const type_t *t)
-{
- if (t->defined)
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- t->name, t->loc_info.input_name, t->loc_info.line_number);
-}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 81eaba5556b..004f7fc7b0d 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -569,6 +569,25 @@ type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref
return runtimeclass;
}
+type_t *type_apicontract_declare(char *name, struct namespace *namespace)
+{
+ type_t *type = get_type(TYPE_APICONTRACT, name, namespace, 0);
+ if (type_get_type_detect_alias(type) != TYPE_APICONTRACT)
+ error_loc("apicontract %s previously not declared a apicontract at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ return type;
+}
+
+type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs)
+{
+ if (apicontract->defined)
+ error_loc("apicontract %s already defined at %s:%d\n",
+ apicontract->name, apicontract->loc_info.input_name, apicontract->loc_info.line_number);
+ apicontract->attrs = check_apicontract_attrs(apicontract->name, attrs);
+ apicontract->defined = TRUE;
+ return apicontract;
+}
+
int type_is_equal(const type_t *type1, const type_t *type2)
{
if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 280d2e722cf..7c19da8e045 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -29,6 +29,7 @@ enum name_type {
NAME_C
};
+attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
@@ -58,6 +59,8 @@ type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *att
void type_module_define(type_t *module, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *ifaces);
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_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);
int type_is_equal(const type_t *type1, const type_t *type2);
const char *type_get_name(const type_t *type, enum name_type name_type);
char *gen_name(void);
--
2.20.1

View File

@@ -0,0 +1,146 @@
From fd50398643cafcfa3868a9e47429db7136a16ef5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 11:02:09 +0100
Subject: [PATCH] widl: Factor and cleanup module type declaration and
definition.
---
tools/widl/parser.y | 20 ++++++--------------
tools/widl/typetree.c | 27 +++++++++++++++------------
tools/widl/typetree.h | 5 +++--
3 files changed, 24 insertions(+), 28 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 8c805e481f8..782ed39643c 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -95,7 +95,6 @@ static attr_list_t *check_struct_attrs(attr_list_t *attrs);
static attr_list_t *check_union_attrs(attr_list_t *attrs);
static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
-static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
const char *get_attr_display_name(enum attr_type type);
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
@@ -285,7 +284,7 @@ static typelib_t *current_typelib;
%type <type> inherit interface interfacedef
%type <type> interfaceref
%type <type> dispinterface dispinterfacedef
-%type <type> module modulehdr moduledef
+%type <type> module moduledef
%type <str> namespacedef
%type <type> base_type int_std
%type <type> enumdef structdef uniondef typedecl
@@ -985,19 +984,12 @@ interfaceref:
| tDISPINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
;
-module: tMODULE aIDENTIFIER { $$ = type_new_module($2); }
- | tMODULE aKNOWNTYPE { $$ = type_new_module($2); }
+module: tMODULE aIDENTIFIER { $$ = type_module_declare($2); }
+ | tMODULE aKNOWNTYPE { $$ = type_module_declare($2); }
;
-modulehdr: attributes module { $$ = $2;
- $$->attrs = check_module_attrs($2->name, $1);
- }
- ;
-
-moduledef: modulehdr '{' int_statements '}'
- semicolon_opt { $$ = $1;
- type_module_define($$, $3);
- }
+moduledef: attributes module '{' int_statements '}' semicolon_opt
+ { $$ = type_module_define($2, $1, $4); }
;
storage_cls_spec:
@@ -2476,7 +2468,7 @@ attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
return attrs;
}
-static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs)
+attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs)
{
const attr_t *attr;
if (!attrs) return attrs;
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 004f7fc7b0d..b3f0725f00e 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -195,16 +195,6 @@ type_t *type_new_alias(const decl_spec_t *t, const char *name)
return a;
}
-type_t *type_new_module(char *name)
-{
- type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
- if (type->type_type != TYPE_MODULE || type->defined)
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- type->name, type->loc_info.input_name, type->loc_info.line_number);
- type->name = name;
- return type;
-}
-
type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
unsigned int dim, expr_t *size_is, expr_t *length_is)
{
@@ -519,12 +509,25 @@ type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *att
return dispiface;
}
-void type_module_define(type_t *module, statement_list_t *stmts)
+type_t *type_module_declare(char *name)
+{
+ type_t *type = get_type(TYPE_MODULE, name, NULL, 0);
+ if (type_get_type_detect_alias(type) != TYPE_MODULE)
+ error_loc("module %s previously not declared a module at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ return type;
+}
+
+type_t *type_module_define(type_t* module, attr_list_t *attrs, statement_list_t *stmts)
{
- if (module->details.module) error_loc("multiple definition error\n");
+ if (module->defined)
+ error_loc("module %s already defined at %s:%d\n",
+ module->name, module->loc_info.input_name, module->loc_info.line_number);
+ module->attrs = check_module_attrs(module->name, attrs);
module->details.module = xmalloc(sizeof(*module->details.module));
module->details.module->stmts = stmts;
module->defined = TRUE;
+ return module;
}
type_t *type_coclass_declare(char *name)
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 7c19da8e045..8e04537ab4d 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -33,12 +33,13 @@ attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
+attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs);
type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(type_t *ref);
type_t *type_new_alias(const decl_spec_t *t, const char *name);
-type_t *type_new_module(char *name);
+type_t *type_module_declare(char *name);
type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
unsigned int dim, expr_t *size_is, expr_t *length_is);
type_t *type_new_basic(enum type_basic_type basic_type);
@@ -56,7 +57,7 @@ type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit
type_t *type_dispinterface_declare(char *name);
type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t *props, var_list_t *methods);
type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *attrs, type_t *iface);
-void type_module_define(type_t *module, statement_list_t *stmts);
+type_t *type_module_define(type_t* module, attr_list_t *attrs, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *ifaces);
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_list_t *ifaces);
type_t *type_apicontract_declare(char *name, struct namespace *namespace);
--
2.20.1

View File

@@ -0,0 +1,159 @@
From bc7044d3cd826d7b3e01566514f9515c3fd7bc5c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 16:46:40 +0100
Subject: [PATCH] widl: Fold aIDENTIFIER / aKNOWNTYPE rules together.
Splitting t_ident rule as typename / m_typename rules.
---
tools/widl/parser.y | 55 ++++++++++++++++++---------------------------
1 file changed, 22 insertions(+), 33 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 782ed39643c..2d527805c14 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -305,7 +305,8 @@ static typelib_t *current_typelib;
%type <type> apicontract apicontract_def
%type <num> contract_ver
%type <num> pointer_type threading_type marshaling_behavior version
-%type <str> libraryhdr callconv cppquote importlib import t_ident
+%type <str> libraryhdr callconv cppquote importlib import
+%type <str> typename m_typename
%type <uuid> uuid_string
%type <import> import_start
%type <typelib> library_start librarydef
@@ -459,8 +460,7 @@ importlib: tIMPORTLIB '(' aSTRING ')'
semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3, current_typelib); }
;
-libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
- | tLIBRARY aKNOWNTYPE { $$ = $2; }
+libraryhdr: tLIBRARY typename { $$ = $2; }
;
library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1));
if (!parse_only && do_typelib) current_typelib = $$;
@@ -715,7 +715,7 @@ enum: enum_member '=' expr_int_const { $$ = reg_const($1);
}
;
-enumdef: tENUM t_ident '{' enums '}' { $$ = type_new_enum($2, current_namespace, TRUE, $4); }
+enumdef: tENUM m_typename '{' enums '}' { $$ = type_new_enum($2, current_namespace, TRUE, $4); }
;
m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
@@ -847,14 +847,15 @@ m_ident: { $$ = NULL; }
| ident
;
-t_ident: { $$ = NULL; }
- | aIDENTIFIER { $$ = $1; }
- | aKNOWNTYPE { $$ = $1; }
+m_typename: { $$ = NULL; }
+ | typename
;
-ident: aIDENTIFIER { $$ = make_var($1); }
-/* some "reserved words" used in attributes are also used as field names in some MS IDL files */
- | aKNOWNTYPE { $$ = make_var($<str>1); }
+typename: aIDENTIFIER
+ | aKNOWNTYPE
+ ;
+
+ident: typename { $$ = make_var($1); }
;
base_type: tBYTE { $$ = find_type_or_error($<str>1); }
@@ -895,26 +896,21 @@ qualified_type:
| aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; }
;
-coclass: tCOCLASS aIDENTIFIER { $$ = type_coclass_declare($2); }
- | tCOCLASS aKNOWNTYPE { $$ = type_coclass_declare($2); }
+coclass: tCOCLASS typename { $$ = type_coclass_declare($2); }
;
coclassdef: attributes coclass '{' class_interfaces '}' semicolon_opt
{ $$ = type_coclass_define($2, $1, $4); }
;
-runtimeclass:
- tRUNTIMECLASS aIDENTIFIER { $$ = type_runtimeclass_declare($2, current_namespace); }
- | tRUNTIMECLASS aKNOWNTYPE { $$ = type_runtimeclass_declare($2, current_namespace); }
+runtimeclass: tRUNTIMECLASS typename { $$ = type_runtimeclass_declare($2, current_namespace); }
;
runtimeclass_def: attributes runtimeclass '{' class_interfaces '}' semicolon_opt
{ $$ = type_runtimeclass_define($2, $1, $4); }
;
-apicontract:
- tAPICONTRACT aIDENTIFIER { $$ = type_apicontract_declare($2, current_namespace); }
- | tAPICONTRACT aKNOWNTYPE { $$ = type_apicontract_declare($2, current_namespace); }
+apicontract: tAPICONTRACT typename { $$ = type_apicontract_declare($2, current_namespace); }
;
apicontract_def: attributes apicontract '{' '}' semicolon_opt
@@ -933,9 +929,7 @@ class_interface:
m_attributes interfaceref ';' { $$ = make_ifref($2); $$->attrs = $1; }
;
-dispinterface:
- tDISPINTERFACE aIDENTIFIER { $$ = type_dispinterface_declare($2); }
- | tDISPINTERFACE aKNOWNTYPE { $$ = type_dispinterface_declare($2); }
+dispinterface: tDISPINTERFACE typename { $$ = type_dispinterface_declare($2); }
;
dispattributes: attributes { $$ = append_attr($1, make_attr(ATTR_DISPINTERFACE)); }
@@ -960,9 +954,7 @@ inherit: { $$ = NULL; }
| ':' qualified_type { $$ = $2; }
;
-interface:
- tINTERFACE aIDENTIFIER { $$ = type_interface_declare($2, current_namespace); }
- | tINTERFACE aKNOWNTYPE { $$ = type_interface_declare($2, current_namespace); }
+interface: tINTERFACE typename { $$ = type_interface_declare($2, current_namespace); }
;
interfacedef: attributes interface inherit
@@ -978,14 +970,11 @@ interfacedef: attributes interface inherit
;
interfaceref:
- tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
- | tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
- | tDISPINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
- | tDISPINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
+ tINTERFACE typename { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
+ | tDISPINTERFACE typename { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
;
-module: tMODULE aIDENTIFIER { $$ = type_module_declare($2); }
- | tMODULE aKNOWNTYPE { $$ = type_module_declare($2); }
+module: tMODULE typename { $$ = type_module_declare($2); }
;
moduledef: attributes module '{' int_statements '}' semicolon_opt
@@ -1153,7 +1142,7 @@ pointer_type:
| tPTR { $$ = FC_FP; }
;
-structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4); }
+structdef: tSTRUCT m_typename '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4); }
;
type: tVOID { $$ = type_new_void(); }
@@ -1175,9 +1164,9 @@ typedef: m_attributes tTYPEDEF m_attributes decl_spec declarator_list
}
;
-uniondef: tUNION t_ident '{' ne_union_fields '}'
+uniondef: tUNION m_typename '{' ne_union_fields '}'
{ $$ = type_new_nonencapsulated_union($2, TRUE, $4); }
- | tUNION t_ident
+ | tUNION m_typename
tSWITCH '(' s_field ')'
m_ident '{' cases '}' { $$ = type_new_encapsulated_union($2, $5, $7, $9); }
;
--
2.20.1

View File

@@ -1,156 +0,0 @@
From 2719c1018570b5fed5058541f54a3334044de160 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Fri, 25 Sep 2020 17:13:47 +0200
Subject: [PATCH] widl: Support using qualified names for interfaces.
And make qualified name lookup more robust, only looking for types in
the lookup namespace if it's active.
---
include/windows.media.speechsynthesis.idl | 2 +-
tools/widl/parser.y | 58 +++++++++++++++--------
2 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl
index 71c51b74c0c..502261f79c6 100644
--- a/include/windows.media.speechsynthesis.idl
+++ b/include/windows.media.speechsynthesis.idl
@@ -64,7 +64,7 @@ namespace Windows {
]
runtimeclass VoiceInformation
{
- [default] interface IVoiceInformation;
+ [default] interface Windows.Media.SpeechSynthesis.IVoiceInformation;
}
}
}
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 480552e3723..1e3e254ec8c 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -75,6 +75,8 @@ static void append_chain_callconv(type_t *chain, char *callconv);
static warning_list_t *append_warning(warning_list_t *, int);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
+static type_t *get_qualified_type(enum type_type type, char *name, int t);
+static type_t *find_qualified_type_or_error(const char *name, int t);
static type_t *find_type_or_error(const char *name, int t);
static type_t *find_type_or_error2(char *name, int t);
@@ -82,7 +84,6 @@ static var_t *reg_const(var_t *var);
static void push_namespace(const char *name);
static void pop_namespace(const char *name);
-static void init_lookup_namespace(const char *name);
static void push_lookup_namespace(const char *name);
static void check_arg_attrs(const var_t *arg);
@@ -295,7 +296,7 @@ static typelib_t *current_typelib;
%type <str> namespacedef
%type <type> base_type int_std
%type <type> enumdef structdef uniondef typedecl
-%type <type> type qualified_seq qualified_type
+%type <type> type qualified_type
%type <ifref> class_interface
%type <ifref_list> class_interfaces
%type <var> arg ne_union_field union_field s_field case enum enum_member declaration
@@ -888,15 +889,15 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
| tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); }
;
-qualified_seq:
- aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
- | aIDENTIFIER '.' { push_lookup_namespace($1); } qualified_seq { $$ = $4; }
- ;
+namespace_pfx:
+ aNAMESPACE '.' { push_lookup_namespace($1); }
+ | namespace_pfx aNAMESPACE '.' { push_lookup_namespace($2); }
+ ;
qualified_type:
- aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
- | aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; }
- ;
+ aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
+ | namespace_pfx aKNOWNTYPE { $$ = find_qualified_type_or_error($2, 0); }
+ ;
coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); }
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0);
@@ -994,6 +995,8 @@ inherit: { $$ = NULL; }
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
| tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
+ | tINTERFACE namespace_pfx aIDENTIFIER { $$ = get_qualified_type(TYPE_INTERFACE, $3, 0); }
+ | tINTERFACE namespace_pfx aKNOWNTYPE { $$ = get_qualified_type(TYPE_INTERFACE, $3, 0); }
;
interfacehdr: attributes interface { $$ = $2;
@@ -1970,12 +1973,6 @@ static void pop_namespace(const char *name)
current_namespace = current_namespace->parent;
}
-static void init_lookup_namespace(const char *name)
-{
- if (!(lookup_namespace = find_sub_namespace(&global_namespace, name)))
- error_loc("namespace '%s' not found\n", name);
-}
-
static void push_lookup_namespace(const char *name)
{
struct namespace *namespace;
@@ -2093,11 +2090,29 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
return NULL;
}
+static type_t *get_qualified_type(enum type_type type_type, char *name, int t)
+{
+ type_t *type = get_type(type_type, name, lookup_namespace, t);
+ lookup_namespace = &global_namespace;
+ return type;
+}
+
+static type_t *find_qualified_type_or_error(const char *name, int t)
+{
+ type_t *type;
+ if (!(type = find_type(name, lookup_namespace, t)))
+ {
+ error_loc("type '%s' not found\n", name);
+ return NULL;
+ }
+ lookup_namespace = &global_namespace;
+ return type;
+}
+
static type_t *find_type_or_error(const char *name, int t)
{
type_t *type;
- if (!(type = find_type(name, current_namespace, t)) &&
- !(type = find_type(name, lookup_namespace, t)))
+ if (!(type = find_type(name, current_namespace, t)))
{
error_loc("type '%s' not found\n", name);
return NULL;
@@ -2114,15 +2129,16 @@ static type_t *find_type_or_error2(char *name, int t)
int is_type(const char *name)
{
- return find_type(name, current_namespace, 0) != NULL ||
- find_type(name, lookup_namespace, 0) != NULL;
+ if (lookup_namespace != &global_namespace)
+ return find_type(name, lookup_namespace, 0) != NULL;
+ else
+ return find_type(name, current_namespace, 0) != NULL;
}
int is_namespace(const char *name)
{
if (!winrt_mode) return 0;
- return find_sub_namespace(current_namespace, name) != NULL ||
- find_sub_namespace(&global_namespace, name) != NULL;
+ return find_sub_namespace(lookup_namespace, name) != NULL;
}
type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t)
--
2.29.2

View File

@@ -0,0 +1,126 @@
From f3dedfb67b596ff167e464bc2469be8a00f01be2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 00:20:02 +0100
Subject: [PATCH] widl: Add explicit namespace parameter to find_type_or_error.
---
tools/widl/parser.y | 37 ++++++++++++++++++-------------------
1 file changed, 18 insertions(+), 19 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 2d527805c14..17a3727b114 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -75,7 +75,7 @@ static void append_chain_callconv(type_t *chain, char *callconv);
static warning_list_t *append_warning(warning_list_t *, int);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
-static type_t *find_type_or_error(const char *name);
+static type_t *find_type_or_error(struct namespace *parent, const char *name);
static var_t *reg_const(var_t *var);
@@ -858,17 +858,17 @@ typename: aIDENTIFIER
ident: typename { $$ = make_var($1); }
;
-base_type: tBYTE { $$ = find_type_or_error($<str>1); }
- | tWCHAR { $$ = find_type_or_error($<str>1); }
+base_type: tBYTE { $$ = find_type_or_error(NULL, $<str>1); }
+ | tWCHAR { $$ = find_type_or_error(NULL, $<str>1); }
| int_std
| tSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), -1); }
| tUNSIGNED int_std { $$ = type_new_int(type_basic_get_type($2), 1); }
| tUNSIGNED { $$ = type_new_int(TYPE_BASIC_INT, 1); }
- | tFLOAT { $$ = find_type_or_error($<str>1); }
- | tDOUBLE { $$ = find_type_or_error($<str>1); }
- | tBOOLEAN { $$ = find_type_or_error($<str>1); }
- | tERRORSTATUST { $$ = find_type_or_error($<str>1); }
- | tHANDLET { $$ = find_type_or_error($<str>1); }
+ | tFLOAT { $$ = find_type_or_error(NULL, $<str>1); }
+ | tDOUBLE { $$ = find_type_or_error(NULL, $<str>1); }
+ | tBOOLEAN { $$ = find_type_or_error(NULL, $<str>1); }
+ | tERRORSTATUST { $$ = find_type_or_error(NULL, $<str>1); }
+ | tHANDLET { $$ = find_type_or_error(NULL, $<str>1); }
;
m_int:
@@ -887,12 +887,12 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
;
qualified_seq:
- aKNOWNTYPE { $$ = find_type_or_error($1); }
+ aKNOWNTYPE { $$ = find_type_or_error(lookup_namespace, $1); }
| aIDENTIFIER '.' { push_lookup_namespace($1); } qualified_seq { $$ = $4; }
;
qualified_type:
- aKNOWNTYPE { $$ = find_type_or_error($1); }
+ aKNOWNTYPE { $$ = find_type_or_error(current_namespace, $1); }
| aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; }
;
@@ -965,7 +965,7 @@ interfacedef: attributes interface inherit
* definition of a derived class, I'll try to support it with this rule */
| attributes interface ':' aIDENTIFIER
'{' import int_statements '}'
- semicolon_opt { $$ = type_interface_define($2, $1, find_type_or_error($4), $7); }
+ semicolon_opt { $$ = type_interface_define($2, $1, find_type_or_error(current_namespace, $4), $7); }
| dispinterfacedef semicolon_opt { $$ = $1; }
;
@@ -1189,14 +1189,14 @@ acf_int_statements
acf_int_statement
: tTYPEDEF acf_attributes aKNOWNTYPE ';'
- { type_t *type = find_type_or_error($3);
+ { type_t *type = find_type_or_error(current_namespace, $3);
type->attrs = append_attr_list(type->attrs, $2);
}
;
acf_interface
: acf_attributes tINTERFACE aKNOWNTYPE '{' acf_int_statements '}'
- { type_t *iface = find_type_or_error($3);
+ { type_t *iface = find_type_or_error(current_namespace, $3);
if (type_get_type(iface) != TYPE_INTERFACE)
error_loc("%s is not an interface\n", iface->name);
iface->attrs = append_attr_list(iface->attrs, $1);
@@ -2034,13 +2034,12 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
return NULL;
}
-static type_t *find_type_or_error(const char *name)
+static type_t *find_type_or_error(struct namespace *namespace, const char *name)
{
type_t *type;
- if (!(type = find_type(name, current_namespace, 0)) &&
- !(type = find_type(name, lookup_namespace, 0)))
+ if (!(type = find_type(name, namespace, 0)))
{
- error_loc("type '%s' not found\n", name);
+ error_loc("type '%s' not found in %s namespace\n", name, namespace && namespace->name ? namespace->name : "global");
return NULL;
}
return type;
@@ -2851,7 +2850,7 @@ static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func)
* function */
var_t *idl_handle = make_var(xstrdup("IDL_handle"));
idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
- idl_handle->declspec.type = find_type_or_error("handle_t");
+ idl_handle->declspec.type = find_type_or_error(NULL, "handle_t");
type_function_add_head_arg(func->declspec.type, idl_handle);
}
}
@@ -3141,7 +3140,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls, int declonl
LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
{
var_t *var = decl->var;
- type_t *type = find_type_or_error(var->name);
+ type_t *type = find_type_or_error(current_namespace, var->name);
*type_list = xmalloc(sizeof(type_list_t));
(*type_list)->type = type;
(*type_list)->next = NULL;
--
2.20.1

View File

@@ -0,0 +1,134 @@
From 5d47a8f72439a481b5f7ae1700488d9447bf74eb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 00:33:21 +0100
Subject: [PATCH] widl: Use explicit namespace parameter for qualified names.
Instead of buggy alternate lookup namespace stack.
---
tools/widl/parser.y | 52 ++++++++++++++++++++++-----------------------
1 file changed, 25 insertions(+), 27 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 17a3727b114..e4834a06e23 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -76,13 +76,12 @@ static warning_list_t *append_warning(warning_list_t *, int);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
static type_t *find_type_or_error(struct namespace *parent, const char *name);
+static struct namespace *find_namespace_or_error(struct namespace *namespace, const char *name);
static var_t *reg_const(var_t *var);
static void push_namespace(const char *name);
static void pop_namespace(const char *name);
-static void init_lookup_namespace(const char *name);
-static void push_lookup_namespace(const char *name);
static void check_arg_attrs(const var_t *arg);
static void check_statements(const statement_list_t *stmts, int is_inside_library);
@@ -120,7 +119,6 @@ static struct namespace global_namespace = {
};
static struct namespace *current_namespace = &global_namespace;
-static struct namespace *lookup_namespace = &global_namespace;
static typelib_t *current_typelib;
@@ -152,6 +150,7 @@ static typelib_t *current_typelib;
enum storage_class stgclass;
enum type_qualifier type_qualifier;
enum function_specifier function_specifier;
+ struct namespace *namespace;
}
%token <str> aIDENTIFIER aPRAGMA
@@ -288,7 +287,7 @@ static typelib_t *current_typelib;
%type <str> namespacedef
%type <type> base_type int_std
%type <type> enumdef structdef uniondef typedecl
-%type <type> type qualified_seq qualified_type
+%type <type> type qualified_type
%type <ifref> class_interface
%type <ifref_list> class_interfaces
%type <var> arg ne_union_field union_field s_field case enum enum_member declaration
@@ -314,6 +313,7 @@ static typelib_t *current_typelib;
%type <stmt_list> gbl_statements imp_statements int_statements
%type <warning_list> warnings
%type <num> allocate_option_list allocate_option
+%type <namespace> namespace_pfx
%left ','
%right '?' ':'
@@ -886,15 +886,16 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
| tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); }
;
-qualified_seq:
- aKNOWNTYPE { $$ = find_type_or_error(lookup_namespace, $1); }
- | aIDENTIFIER '.' { push_lookup_namespace($1); } qualified_seq { $$ = $4; }
- ;
+namespace_pfx:
+ aNAMESPACE '.' { $$ = find_namespace_or_error(&global_namespace, $1); }
+ | namespace_pfx aNAMESPACE '.' { $$ = find_namespace_or_error($1, $2); }
+ | namespace_pfx aIDENTIFIER '.' { $$ = find_namespace_or_error($1, $2); }
+ ;
qualified_type:
- aKNOWNTYPE { $$ = find_type_or_error(current_namespace, $1); }
- | aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; }
- ;
+ aKNOWNTYPE { $$ = find_type_or_error(current_namespace, $1); }
+ | namespace_pfx typename { $$ = find_type_or_error($1, $2); }
+ ;
coclass: tCOCLASS typename { $$ = type_coclass_declare($2); }
;
@@ -1911,20 +1912,6 @@ static void pop_namespace(const char *name)
current_namespace = current_namespace->parent;
}
-static void init_lookup_namespace(const char *name)
-{
- if (!(lookup_namespace = find_sub_namespace(&global_namespace, name)))
- error_loc("namespace '%s' not found\n", name);
-}
-
-static void push_lookup_namespace(const char *name)
-{
- struct namespace *namespace;
- if (!(namespace = find_sub_namespace(lookup_namespace, name)))
- error_loc("namespace '%s' not found\n", name);
- lookup_namespace = namespace;
-}
-
struct rtype {
const char *name;
type_t *type;
@@ -2045,10 +2032,21 @@ static type_t *find_type_or_error(struct namespace *namespace, const char *name)
return type;
}
+static struct namespace *find_namespace_or_error(struct namespace *parent, const char *name)
+{
+ struct namespace *namespace = NULL;
+
+ if (!winrt_mode)
+ error_loc("namespaces are only supported in winrt mode.\n");
+ else if (!(namespace = find_sub_namespace(parent, name)))
+ error_loc("namespace '%s' not found in '%s'\n", name, parent->name);
+
+ return namespace;
+}
+
int is_type(const char *name)
{
- return find_type(name, current_namespace, 0) != NULL ||
- find_type(name, lookup_namespace, 0) != NULL;
+ return find_type(name, current_namespace, 0) != NULL;
}
int is_namespace(const char *name)
--
2.20.1

View File

@@ -0,0 +1,86 @@
From 170f789b5924560ff2a80565880d73a76ea6c021 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 11:35:33 +0100
Subject: [PATCH] widl: Disallow qualified types in expressions.
MIDL WinRT mode only supports a limited subset of original IDL syntax
anyway, and this will save some conflicts when removing the lexer trick
for namespaces.
---
tools/widl/parser.y | 24 ++++++++++++++++++------
1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index e4834a06e23..9fb6772ba33 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -279,7 +279,7 @@ static typelib_t *current_typelib;
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
%type <function_specifier> function_specifier
-%type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
+%type <declspec> decl_spec unqualified_decl_spec decl_spec_no_type m_decl_spec_no_type
%type <type> inherit interface interfacedef
%type <type> interfaceref
%type <type> dispinterface dispinterfacedef
@@ -287,7 +287,7 @@ static typelib_t *current_typelib;
%type <str> namespacedef
%type <type> base_type int_std
%type <type> enumdef structdef uniondef typedecl
-%type <type> type qualified_type
+%type <type> type unqualified_type qualified_type
%type <ifref> class_interface
%type <ifref_list> class_interfaces
%type <var> arg ne_union_field union_field s_field case enum enum_member declaration
@@ -763,9 +763,9 @@ expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); }
| '*' expr %prec PPTR { $$ = make_expr1(EXPR_PPTR, $2); }
| expr MEMBERPTR aIDENTIFIER { $$ = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, $1), make_exprs(EXPR_IDENTIFIER, $3)); }
| expr '.' aIDENTIFIER { $$ = make_expr2(EXPR_MEMBER, $1, make_exprs(EXPR_IDENTIFIER, $3)); }
- | '(' decl_spec m_abstract_declarator ')' expr %prec CAST
+ | '(' unqualified_decl_spec m_abstract_declarator ')' expr %prec CAST
{ $$ = make_exprt(EXPR_CAST, declare_var(NULL, $2, $3, 0), $5); free($2); free($3); }
- | tSIZEOF '(' decl_spec m_abstract_declarator ')'
+ | tSIZEOF '(' unqualified_decl_spec m_abstract_declarator ')'
{ $$ = make_exprt(EXPR_SIZEOF, declare_var(NULL, $3, $4, 0), NULL); free($3); free($4); }
| expr '[' expr ']' { $$ = make_expr2(EXPR_ARRAY, $1, $3); }
| '(' expr ')' { $$ = $2; }
@@ -1005,6 +1005,12 @@ decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, STG_NON
{ $$ = make_decl_spec($2, $1, $3, STG_NONE, 0, 0); }
;
+unqualified_decl_spec: unqualified_type m_decl_spec_no_type
+ { $$ = make_decl_spec($1, $2, NULL, STG_NONE, 0, 0); }
+ | decl_spec_no_type unqualified_type m_decl_spec_no_type
+ { $$ = make_decl_spec($2, $1, $3, STG_NONE, 0, 0); }
+ ;
+
m_decl_spec_no_type: { $$ = NULL; }
| decl_spec_no_type
;
@@ -1146,8 +1152,8 @@ pointer_type:
structdef: tSTRUCT m_typename '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4); }
;
-type: tVOID { $$ = type_new_void(); }
- | qualified_type { $$ = $1; }
+unqualified_type:
+ tVOID { $$ = type_new_void(); }
| base_type { $$ = $1; }
| enumdef { $$ = $1; }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
@@ -1156,6 +1162,12 @@ type: tVOID { $$ = type_new_void(); }
| uniondef { $$ = $1; }
| tUNION aIDENTIFIER { $$ = type_new_nonencapsulated_union($2, FALSE, NULL); }
| tSAFEARRAY '(' type ')' { $$ = make_safearray($3); }
+ | aKNOWNTYPE { $$ = find_type_or_error(current_namespace, $1); }
+ ;
+
+type:
+ unqualified_type
+ | namespace_pfx typename { $$ = find_type_or_error($1, $2); }
;
typedef: m_attributes tTYPEDEF m_attributes decl_spec declarator_list
--
2.20.1

View File

@@ -0,0 +1,84 @@
From 7eafbb307b59167e9af8ceb683990a2f3b44b0cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 00:40:58 +0100
Subject: [PATCH] widl: Remove aNAMESPACE token from the lexer.
---
tools/widl/parser.h | 1 -
tools/widl/parser.l | 2 +-
tools/widl/parser.y | 13 ++-----------
3 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/tools/widl/parser.h b/tools/widl/parser.h
index a6dc94ae6b8..a67b160d48a 100644
--- a/tools/widl/parser.h
+++ b/tools/widl/parser.h
@@ -38,7 +38,6 @@ void pop_import(void);
#define parse_only import_stack_ptr
int is_type(const char *name);
-int is_namespace(const char *name);
int do_warning(char *toggle, warning_list_t *wnum);
int is_warning_enabled(int warning);
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 7e20d30e7f0..8acc9c9590c 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -468,7 +468,7 @@ static int kw_token(const char *kw)
return kwp->token;
}
parser_lval.str = xstrdup(kw);
- return is_type(kw) ? aKNOWNTYPE : is_namespace(kw) ? aNAMESPACE : aIDENTIFIER;
+ return is_type(kw) ? aKNOWNTYPE : aIDENTIFIER;
}
static int attr_token(const char *kw)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 9fb6772ba33..d3a79e9fcb7 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -154,7 +154,7 @@ static typelib_t *current_typelib;
}
%token <str> aIDENTIFIER aPRAGMA
-%token <str> aKNOWNTYPE aNAMESPACE
+%token <str> aKNOWNTYPE
%token <num> aNUM aHEXNUM
%token <dbl> aDOUBLE
%token <str> aSTRING aWSTRING aSQSTRING
@@ -887,8 +887,7 @@ int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
;
namespace_pfx:
- aNAMESPACE '.' { $$ = find_namespace_or_error(&global_namespace, $1); }
- | namespace_pfx aNAMESPACE '.' { $$ = find_namespace_or_error($1, $2); }
+ aIDENTIFIER '.' { $$ = find_namespace_or_error(&global_namespace, $1); }
| namespace_pfx aIDENTIFIER '.' { $$ = find_namespace_or_error($1, $2); }
;
@@ -919,7 +918,6 @@ apicontract_def: attributes apicontract '{' '}' semicolon_opt
;
namespacedef: tNAMESPACE aIDENTIFIER { $$ = $2; }
- | tNAMESPACE aNAMESPACE { $$ = $2; }
;
class_interfaces: { $$ = NULL; }
@@ -2061,13 +2059,6 @@ int is_type(const char *name)
return find_type(name, current_namespace, 0) != NULL;
}
-int is_namespace(const char *name)
-{
- if (!winrt_mode) return 0;
- return find_sub_namespace(current_namespace, name) != NULL ||
- find_sub_namespace(&global_namespace, name) != NULL;
-}
-
type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t)
{
type_t *tp;
--
2.20.1

View File

@@ -0,0 +1,38 @@
From fcb515de7ef61b806c7da1fc57875fb60edb59db Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 13:40:11 +0100
Subject: [PATCH] widl: Fold inherit cases by using typename rule in
qualified_type.
---
tools/widl/parser.y | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index d3a79e9fcb7..bbf71a2e3ef 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -892,7 +892,7 @@ namespace_pfx:
;
qualified_type:
- aKNOWNTYPE { $$ = find_type_or_error(current_namespace, $1); }
+ typename { $$ = find_type_or_error(current_namespace, $1); }
| namespace_pfx typename { $$ = find_type_or_error($1, $2); }
;
@@ -960,11 +960,6 @@ interfacedef: attributes interface inherit
'{' int_statements '}' semicolon_opt { $$ = type_interface_define($2, $1, $3, $5);
check_async_uuid($$);
}
-/* MIDL is able to import the definition of a base class from inside the
- * definition of a derived class, I'll try to support it with this rule */
- | attributes interface ':' aIDENTIFIER
- '{' import int_statements '}'
- semicolon_opt { $$ = type_interface_define($2, $1, find_type_or_error(current_namespace, $4), $7); }
| dispinterfacedef semicolon_opt { $$ = $1; }
;
--
2.20.1

View File

@@ -1,136 +0,0 @@
From 99bc0225cdc921dc87d3906de145533690ad7816 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 1 Dec 2020 14:41:01 +0100
Subject: [PATCH] widl: Introduce new strappend helper.
And use it for format_namespace to grow buffer as needed.
---
tools/widl/typetree.c | 46 ++++++++++++++-----------------------------
tools/widl/utils.c | 37 ++++++++++++++++++++++++++++++++++
tools/widl/utils.h | 1 +
3 files changed, 53 insertions(+), 31 deletions(-)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index f451f8f3a1a..95c04c245b8 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -89,41 +89,25 @@ const char *type_get_name(const type_t *type, enum name_type name_type)
return NULL;
}
-static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator, const char *abi_prefix)
+static size_t append_namespace(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *separator, const char *abi_prefix)
{
- if(is_global_namespace(namespace)) {
- if(!abi_prefix) return ptr;
- strcpy(ptr, abi_prefix);
- strcat(ptr, separator);
- return ptr + strlen(ptr);
- }
-
- ptr = append_namespace(ptr, namespace->parent, separator, abi_prefix);
- strcpy(ptr, namespace->name);
- strcat(ptr, separator);
- return ptr + strlen(ptr);
+ int nested = namespace && !is_global_namespace(namespace);
+ const char *name = nested ? namespace->name : abi_prefix;
+ size_t n = 0;
+ if (!name) return 0;
+ if (nested) n += append_namespace(buf, len, pos + n, namespace->parent, separator, abi_prefix);
+ n += strappend(buf, len, pos + n, "%s%s", name, separator);
+ return n;
}
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
- const char *abi_prefix)
+char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
{
- unsigned len = strlen(prefix) + strlen(suffix);
- unsigned sep_len = strlen(separator);
- struct namespace *iter;
- char *ret, *ptr;
-
- if(abi_prefix)
- len += strlen(abi_prefix) + sep_len;
-
- for(iter = namespace; !is_global_namespace(iter); iter = iter->parent)
- len += strlen(iter->name) + sep_len;
-
- ret = xmalloc(len+1);
- strcpy(ret, prefix);
- ptr = append_namespace(ret + strlen(ret), namespace, separator, abi_prefix);
- strcpy(ptr, suffix);
-
- return ret;
+ size_t len = 0, pos = 0;
+ char *buf = NULL;
+ pos += strappend(&buf, &len, pos, "%s", prefix);
+ pos += append_namespace(&buf, &len, pos, namespace, separator, abi_prefix);
+ pos += strappend(&buf, &len, pos, "%s", suffix);
+ return buf;
}
type_t *type_new_function(var_list_t *args)
diff --git a/tools/widl/utils.c b/tools/widl/utils.c
index ea92372c8c7..634bd12a0ba 100644
--- a/tools/widl/utils.c
+++ b/tools/widl/utils.c
@@ -245,6 +245,43 @@ char *strmake( const char* fmt, ... )
}
}
+size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...)
+{
+ size_t size;
+ va_list ap;
+ char *ptr;
+ int n;
+
+ assert( buf && len );
+ assert( (*len == 0 && *buf == NULL) || (*len != 0 && *buf != NULL) );
+
+ if (*buf)
+ {
+ size = *len;
+ ptr = *buf;
+ }
+ else
+ {
+ size = 100;
+ ptr = xmalloc( size );
+ }
+
+ for (;;)
+ {
+ va_start( ap, fmt );
+ n = vsnprintf( ptr + pos, size - pos, fmt, ap );
+ va_end( ap );
+ if (n == -1) size *= 2;
+ else if (pos + (size_t)n >= size) size = pos + n + 1;
+ else break;
+ ptr = xrealloc( ptr, size );
+ }
+
+ *len = size;
+ *buf = ptr;
+ return n;
+}
+
char *xstrdup(const char *str)
{
char *s;
diff --git a/tools/widl/utils.h b/tools/widl/utils.h
index 37406656504..82e0a6ae489 100644
--- a/tools/widl/utils.h
+++ b/tools/widl/utils.h
@@ -45,6 +45,7 @@ void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning_loc_info(const loc_info_t *, const char *s, ...) __attribute__((format (printf, 2, 3)));
void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
char *strmake(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2 )));
+size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...) __attribute__((__format__ (__printf__, 4, 5 )));
char *dup_basename(const char *name, const char *ext);
size_t widl_getline(char **linep, size_t *lenp, FILE *fp);
--
2.29.2

View File

@@ -1,209 +0,0 @@
From 680c7575c78c63e8bc8e971d8f1385175bf5f106 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Mon, 12 Oct 2020 23:23:18 +0200
Subject: [PATCH] widl: Support partially specialized parameterized type.
This allows parameterized types to reference each other with a different
set of parameters. This is required for instance for IIterable<T>, that
needs to reference IIterator<T>.
The partial specialization is recorded by adding a new parameterized
type, referencing the original one as its template. The parameterized
type chain will be resolved all at once when the type is declared.
---
include/windows.foundation.idl | 9 ++++++++
tools/widl/parser.y | 35 +++++++++++++++++++++++++++++
tools/widl/typetree.c | 41 +++++++++++++++++++++++++++++++---
tools/widl/typetree.h | 2 ++
tools/widl/widltypes.h | 1 +
5 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
index ab7c4753c3b..5f7a49c38e4 100644
--- a/include/windows.foundation.idl
+++ b/include/windows.foundation.idl
@@ -127,6 +127,15 @@ namespace Windows {
HRESULT GetMany([in] UINT32 count, [out] T *items, [out, retval] UINT32 *value);
}
+ [
+ contract(Windows.Foundation.FoundationContract, 1.0),
+ uuid(faa585ea-6214-4217-afda-7f46de5869b3)
+ ]
+ interface IIterable<T> : IInspectable
+ {
+ HRESULT First([out, retval] Windows.Foundation.Collections.IIterator<T> **value);
+ }
+
[
contract(Windows.Foundation.FoundationContract, 1.0),
uuid(bbe1fa4c-b0e3-4583-baef-1f1b2e483e56)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 9083df8cf27..61bbe2a50ee 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -302,6 +302,8 @@ static typelib_t *current_typelib;
%type <type> type qualified_type
%type <type> type_parameter
%type <typelist> type_parameters
+%type <type> parameterized_type
+%type <typelist> parameterized_types
%type <typelist> requires required_types
%type <ifref> class_interface
%type <ifref_list> class_interfaces
@@ -912,6 +914,20 @@ qualified_type:
| namespace_pfx aKNOWNTYPE { $$ = find_qualified_type_or_error($2, 0); }
;
+parameterized_type: qualified_type '<' parameterized_types '>'
+ { $$ = find_parameterized_type($1, $3, 0); }
+ ;
+
+parameterized_types:
+ base_type { $$ = append_type(NULL, $1); }
+ | qualified_type { $$ = append_type(NULL, $1); }
+ | qualified_type '*' { $$ = append_type(NULL, type_new_pointer($1)); }
+ | parameterized_type { $$ = append_type(NULL, $1); }
+ | parameterized_type '*' { $$ = append_type(NULL, type_new_pointer($1)); }
+ | parameterized_types ',' parameterized_types
+ { $$ = append_types($1, $3); }
+ ;
+
coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); }
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0);
if (type_get_type_detect_alias($$) != TYPE_COCLASS)
@@ -1004,6 +1020,7 @@ dispinterfacedef: dispinterfacehdr '{'
inherit: { $$ = NULL; }
| ':' qualified_type { $$ = $2; }
+ | ':' parameterized_type { $$ = $2; }
;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
@@ -1030,6 +1047,7 @@ type_parameters:
required_types:
qualified_type { $$ = append_type(NULL, $1); }
+ | parameterized_type { $$ = append_type(NULL, $1); }
| required_types ',' required_types { $$ = append_types($1, $3); }
requires: { $$ = NULL; }
@@ -1251,6 +1269,7 @@ structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_nam
type: tVOID { $$ = type_new_void(); }
| qualified_type { $$ = $1; }
+ | parameterized_type { $$ = $1; }
| base_type { $$ = $1; }
| enumdef { $$ = $1; }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
@@ -3369,3 +3388,19 @@ static void check_def(const type_t *t)
error_loc("%s: redefinition error; original definition was at %s:%d\n",
t->name, t->loc_info.input_name, t->loc_info.line_number);
}
+
+type_t *find_parameterized_type(type_t *type, type_list_t *params, int t)
+{
+ char *name = format_parameterized_type_name(type, params);
+
+ if (parameters_namespace)
+ {
+ assert(type->type_type == TYPE_PARAMETERIZED_TYPE);
+ type = type_parameterized_type_specialize_partial(type, params);
+ }
+ /* FIXME: If not in another parameterized type, we'll have to look for the declared specialization. */
+ else error_loc("parameterized type '%s' not declared\n", name);
+
+ free(name);
+ return type;
+}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 95c04c245b8..d2c472fcca0 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -100,13 +100,40 @@ static size_t append_namespace(char **buf, size_t *len, size_t pos, struct names
return n;
}
+static size_t append_namespaces(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *prefix,
+ const char *separator, const char *suffix, const char *abi_prefix)
+{
+ size_t n = 0;
+ n += strappend(buf, len, pos + n, "%s", prefix);
+ n += append_namespace(buf, len, pos + n, namespace, separator, abi_prefix);
+ n += strappend(buf, len, pos + n, "%s", suffix);
+ return n;
+}
+
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
+{
+ size_t len = 0;
+ char *buf = NULL;
+ append_namespaces(&buf, &len, 0, namespace, prefix, separator, suffix, abi_prefix);
+ return buf;
+}
+
+char *format_parameterized_type_name(type_t *type, type_list_t *params)
{
size_t len = 0, pos = 0;
char *buf = NULL;
- pos += strappend(&buf, &len, pos, "%s", prefix);
- pos += append_namespace(&buf, &len, pos, namespace, separator, abi_prefix);
- pos += strappend(&buf, &len, pos, "%s", suffix);
+ type_list_t *entry;
+
+ pos += strappend(&buf, &len, pos, "%s<", type->name);
+ for (entry = params; entry; entry = entry->next)
+ {
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
+ pos += append_namespaces(&buf, &len, pos, type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL);
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) pos += strappend(&buf, &len, pos, "*");
+ if (entry->next) pos += strappend(&buf, &len, pos, ",");
+ }
+ pos += strappend(&buf, &len, pos, ">");
+
return buf;
}
@@ -447,6 +474,14 @@ static unsigned int compute_method_indexes(type_t *iface)
return idx;
}
+type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params)
+{
+ type_t *new_type = duptype(type, 0);
+ new_type->details.parameterized.type = type;
+ new_type->details.parameterized.params = params;
+ return new_type;
+}
+
void type_parameterized_interface_declare(type_t *type, type_list_t *params)
{
type_t *iface = make_type(TYPE_INTERFACE);
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index 79c5a01ce3a..c46a2629467 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -45,6 +45,8 @@ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_new_runtimeclass(char *name, struct namespace *namespace);
+type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params);
+type_t *find_parameterized_type(type_t *type, type_list_t *params, int t);
void type_parameterized_interface_declare(type_t *type, type_list_t *params);
void type_parameterized_interface_define(type_t *type, type_list_t *params, type_t *inherit, statement_list_t *stmts);
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 2c0ac4003ce..be82342e31a 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -650,6 +650,7 @@ void init_loc_info(loc_info_t *);
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
const char *abi_prefix);
+char *format_parameterized_type_name(type_t *type, type_list_t *params);
static inline enum type_type type_get_type_detect_alias(const type_t *type)
{
--
2.29.2

View File

@@ -0,0 +1,60 @@
From 0a610b81e85384af6c3fe086b50adcf7bc6f77cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Thu, 4 Feb 2021 12:20:26 +0100
Subject: [PATCH] widl: Support referencing qualified interface names.
And split the dispinterface case, which is not supported in WinRT mode.
---
include/windows.media.speechsynthesis.idl | 2 +-
tools/widl/parser.y | 8 +++++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl
index 71c51b74c0c..502261f79c6 100644
--- a/include/windows.media.speechsynthesis.idl
+++ b/include/windows.media.speechsynthesis.idl
@@ -64,7 +64,7 @@ namespace Windows {
]
runtimeclass VoiceInformation
{
- [default] interface IVoiceInformation;
+ [default] interface Windows.Media.SpeechSynthesis.IVoiceInformation;
}
}
}
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index bbf71a2e3ef..b43a1cdd5f2 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -282,6 +282,7 @@ static typelib_t *current_typelib;
%type <declspec> decl_spec unqualified_decl_spec decl_spec_no_type m_decl_spec_no_type
%type <type> inherit interface interfacedef
%type <type> interfaceref
+%type <type> dispinterfaceref
%type <type> dispinterface dispinterfacedef
%type <type> module moduledef
%type <str> namespacedef
@@ -926,6 +927,7 @@ class_interfaces: { $$ = NULL; }
class_interface:
m_attributes interfaceref ';' { $$ = make_ifref($2); $$->attrs = $1; }
+ | m_attributes dispinterfaceref ';' { $$ = make_ifref($2); $$->attrs = $1; }
;
dispinterface: tDISPINTERFACE typename { $$ = type_dispinterface_declare($2); }
@@ -965,7 +967,11 @@ interfacedef: attributes interface inherit
interfaceref:
tINTERFACE typename { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
- | tDISPINTERFACE typename { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
+ | tINTERFACE namespace_pfx typename { $$ = get_type(TYPE_INTERFACE, $3, $2, 0); }
+ ;
+
+dispinterfaceref:
+ tDISPINTERFACE typename { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
;
module: tMODULE typename { $$ = type_module_declare($2); }
--
2.20.1

View File

@@ -1,7 +1,7 @@
From 58ae5534e33ac94eaac4885bb0d9aa31abc5496d Mon Sep 17 00:00:00 2001
From a9478fb534dbb1bc2319a147cd3794112304df68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 11:35:29 +0200
Subject: [PATCH] widl: Support WinRT activatable attribute.
Subject: [PATCH] widl: Support WinRT activatable attribute parsing.
---
tools/widl/parser.l | 1 +
@@ -10,10 +10,10 @@ Subject: [PATCH] widl: Support WinRT activatable attribute.
3 files changed, 5 insertions(+)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 0a5ef3c1b89..e09722d7023 100644
index 8acc9c9590c..d726e76744e 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -321,6 +321,7 @@ static const struct keyword keywords[] = {
@@ -320,6 +320,7 @@ static const struct keyword keywords[] = {
*/
static const struct keyword attr_keywords[] =
{
@@ -22,10 +22,10 @@ index 0a5ef3c1b89..e09722d7023 100644
{"agile", tAGILE, 1},
{"all_nodes", tALLNODES, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index b774b01cdd7..e5a39872524 100644
index b43a1cdd5f2..eaeba90609d 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -173,6 +173,7 @@ static typelib_t *current_typelib;
@@ -166,6 +166,7 @@ static typelib_t *current_typelib;
%token GREATEREQUAL LESSEQUAL
%token LOGICALOR LOGICALAND
%token ELLIPSIS
@@ -33,7 +33,7 @@ index b774b01cdd7..e5a39872524 100644
%token tAGGREGATABLE
%token tAGILE
%token tALLNODES tALLOCATE tANNOTATION
@@ -547,6 +548,7 @@ static_attr: decl_spec ',' contract_req { if ($1->type->type_type != TYPE_INTER
@@ -539,6 +540,7 @@ contract_req: decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICO
}
attribute: { $$ = NULL; }
@@ -41,7 +41,7 @@ index b774b01cdd7..e5a39872524 100644
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
| tAPPOBJECT { $$ = make_attr(ATTR_APPOBJECT); }
@@ -2277,6 +2279,7 @@ struct allowed_attr
@@ -2162,6 +2164,7 @@ struct allowed_attr
struct allowed_attr allowed_attr[] =
{
/* attr { D ACF M I Fn ARG T En Enm St Un Fi L DI M C AC R <display name> } */
@@ -50,7 +50,7 @@ index b774b01cdd7..e5a39872524 100644
/* ATTR_ALLOCATE */ { 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "allocate" },
/* ATTR_ANNOTATION */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "annotation" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 7db2deb1839..a3000a7417b 100644
index 0fba33d6a09..5d4532d6434 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -69,6 +69,7 @@ typedef struct list warning_list_t;
@@ -62,5 +62,5 @@ index 7db2deb1839..a3000a7417b 100644
ATTR_ALLOCATE,
ATTR_ANNOTATION,
--
2.29.2
2.20.1

View File

@@ -1,4 +1,4 @@
From 0a3ad97a115851c604c6291de3fc71ef7c418cba Mon Sep 17 00:00:00 2001
From c0c6947738f5e41804b475f889eeb37161083455 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 14:30:32 +0200
Subject: [PATCH] widl: Support WinRT static attribute parsing.
@@ -10,10 +10,10 @@ Subject: [PATCH] widl: Support WinRT static attribute parsing.
3 files changed, 10 insertions(+)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index 7e20d30e7f0..dd7cdae5338 100644
index d726e76744e..9b93a53b839 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -426,6 +426,7 @@ static const struct keyword attr_keywords[] =
@@ -427,6 +427,7 @@ static const struct keyword attr_keywords[] =
{"size_is", tSIZEIS, 0},
{"source", tSOURCE, 0},
{"standard", tSTANDARD, 1},
@@ -22,18 +22,18 @@ index 7e20d30e7f0..dd7cdae5338 100644
{"string", tSTRING, 0},
{"switch_is", tSWITCHIS, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 1e3e254ec8c..01cdbffe4c7 100644
index eaeba90609d..b8c916f8336 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -285,6 +285,7 @@ static typelib_t *current_typelib;
@@ -277,6 +277,7 @@ static typelib_t *current_typelib;
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
%type <expr> contract_req
+%type <expr> static_attr
%type <type> interfacehdr
%type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
@@ -541,6 +542,11 @@ contract_req: decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICO
%type <function_specifier> function_specifier
@@ -539,6 +540,11 @@ contract_req: decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICO
$$ = make_exprt(EXPR_GTREQL, declare_var(NULL, $1, make_declarator(NULL), 0), $$);
}
@@ -43,9 +43,9 @@ index 1e3e254ec8c..01cdbffe4c7 100644
+ }
+
attribute: { $$ = NULL; }
| tACTIVATABLE '(' contract_req ')' { $$ = make_attrp(ATTR_ACTIVATABLE, $3); }
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
@@ -638,6 +644,7 @@ attribute: { $$ = NULL; }
@@ -637,6 +643,7 @@ attribute: { $$ = NULL; }
| tRETVAL { $$ = make_attr(ATTR_RETVAL); }
| tSIZEIS '(' m_exprs ')' { $$ = make_attrp(ATTR_SIZEIS, $3); }
| tSOURCE { $$ = make_attr(ATTR_SOURCE); }
@@ -53,7 +53,7 @@ index 1e3e254ec8c..01cdbffe4c7 100644
| tSTRICTCONTEXTHANDLE { $$ = make_attr(ATTR_STRICTCONTEXTHANDLE); }
| tSTRING { $$ = make_attr(ATTR_STRING); }
| tSWITCHIS '(' expr ')' { $$ = make_attrp(ATTR_SWITCHIS, $3); }
@@ -2336,6 +2343,7 @@ struct allowed_attr allowed_attr[] =
@@ -2258,6 +2265,7 @@ struct allowed_attr allowed_attr[] =
/* ATTR_RETVAL */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "retval" },
/* ATTR_SIZEIS */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "size_is" },
/* ATTR_SOURCE */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "source" },
@@ -62,10 +62,10 @@ index 1e3e254ec8c..01cdbffe4c7 100644
/* ATTR_STRING */ { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "string" },
/* ATTR_SWITCHIS */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "switch_is" },
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 0fba33d6a09..8e9ba3e4460 100644
index 5d4532d6434..facfff21453 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -162,6 +162,7 @@ enum attr_type
@@ -163,6 +163,7 @@ enum attr_type
ATTR_RETVAL,
ATTR_SIZEIS,
ATTR_SOURCE,
@@ -74,5 +74,5 @@ index 0fba33d6a09..8e9ba3e4460 100644
ATTR_STRING,
ATTR_SWITCHIS,
--
2.29.2
2.20.1

View File

@@ -0,0 +1,56 @@
From 3390b91447ab5cea8f8855cfeb3cd3a6a5041650 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 2 Feb 2021 09:12:08 +0100
Subject: [PATCH] include: Add Windows.Media.SpeechSynthesis.SpeechSynthesizer
runtimeclass.
As an illustration for the newly supported attributes.
---
include/windows.media.speechsynthesis.idl | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/include/windows.media.speechsynthesis.idl b/include/windows.media.speechsynthesis.idl
index 502261f79c6..87497678f30 100644
--- a/include/windows.media.speechsynthesis.idl
+++ b/include/windows.media.speechsynthesis.idl
@@ -24,10 +24,16 @@ import "inspectable.idl";
import "windows.foundation.idl";
namespace Windows {
+ namespace Foundation {
+ interface IClosable;
+ }
namespace Media {
namespace SpeechSynthesis {
typedef enum VoiceGender VoiceGender;
interface IInstalledVoicesStatic;
+ interface IInstalledVoicesStatic2;
+ interface ISpeechSynthesizer;
+ interface ISpeechSynthesizer2;
interface IVoiceInformation;
runtimeclass VoiceInformation;
}
@@ -66,6 +72,20 @@ namespace Windows {
{
[default] interface Windows.Media.SpeechSynthesis.IVoiceInformation;
}
+
+ [
+ activatable(Windows.Foundation.UniversalApiContract, 1.0),
+ contract(Windows.Foundation.UniversalApiContract, 1.0),
+ marshaling_behavior(agile),
+ static(Windows.Media.SpeechSynthesis.IInstalledVoicesStatic, Windows.Foundation.UniversalApiContract, 1.0),
+ static(Windows.Media.SpeechSynthesis.IInstalledVoicesStatic2, Windows.Foundation.UniversalApiContract, 5.0)
+ ]
+ runtimeclass SpeechSynthesizer
+ {
+ [default] interface Windows.Media.SpeechSynthesis.ISpeechSynthesizer;
+ interface Windows.Foundation.IClosable;
+ [contract(Windows.Foundation.UniversalApiContract, 4.0)] interface Windows.Media.SpeechSynthesis.ISpeechSynthesizer2;
+ }
}
}
}
--
2.20.1

View File

@@ -1,18 +1,18 @@
From ca531da15e6fb32e182d83e98857e6945163e083 Mon Sep 17 00:00:00 2001
From 8b5c17d32ec132669fc345bce9616d6631e072ab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 00:31:57 +0200
Subject: [PATCH] widl: Support WinRT requires keyword.
---
tools/widl/parser.l | 1 +
tools/widl/parser.y | 49 ++++++++++++++++++++++++++++++++----------
tools/widl/parser.y | 45 +++++++++++++++++++++++++++++++++---------
tools/widl/typetree.c | 5 ++++-
tools/widl/typetree.h | 9 +++++++-
tools/widl/typetree.h | 9 ++++++++-
tools/widl/widltypes.h | 1 +
5 files changed, 52 insertions(+), 13 deletions(-)
5 files changed, 50 insertions(+), 11 deletions(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l
index dd7cdae5338..0a5ef3c1b89 100644
index 9b93a53b839..946dba84cd6 100644
--- a/tools/widl/parser.l
+++ b/tools/widl/parser.l
@@ -298,6 +298,7 @@ static const struct keyword keywords[] = {
@@ -24,7 +24,7 @@ index dd7cdae5338..0a5ef3c1b89 100644
{"short", tSHORT, 0},
{"signed", tSIGNED, 0},
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 01cdbffe4c7..b774b01cdd7 100644
index b8c916f8336..169a5ba6386 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -38,12 +38,6 @@
@@ -49,7 +49,7 @@ index 01cdbffe4c7..b774b01cdd7 100644
static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right,
@@ -141,6 +137,7 @@ static typelib_t *current_typelib;
@@ -130,6 +126,7 @@ static typelib_t *current_typelib;
expr_t *expr;
expr_list_t *expr_list;
type_t *type;
@@ -57,7 +57,7 @@ index 01cdbffe4c7..b774b01cdd7 100644
var_t *var;
var_list_t *var_list;
declarator_t *declarator;
@@ -249,6 +246,7 @@ static typelib_t *current_typelib;
@@ -240,6 +237,7 @@ static typelib_t *current_typelib;
%token tREADONLY tREF
%token tREGISTER tREPRESENTAS
%token tREQUESTEDIT
@@ -65,19 +65,20 @@ index 01cdbffe4c7..b774b01cdd7 100644
%token tRESTRICTED
%token tRETVAL
%token tRUNTIMECLASS
@@ -298,6 +296,7 @@ static typelib_t *current_typelib;
@@ -291,6 +289,7 @@ static typelib_t *current_typelib;
%type <type> base_type int_std
%type <type> enumdef structdef uniondef typedecl
%type <type> type qualified_type
%type <type> type unqualified_type qualified_type
+%type <typelist> requires required_types
%type <ifref> class_interface
%type <ifref_list> class_interfaces
%type <var> arg ne_union_field union_field s_field case enum enum_member declaration
@@ -1013,19 +1012,27 @@ interfacehdr: attributes interface { $$ = $2;
}
@@ -967,8 +966,16 @@ inherit: { $$ = NULL; }
interface: tINTERFACE typename { $$ = type_interface_declare($2, current_namespace); }
;
-interfacedef: interfacehdr inherit
-interfacedef: attributes interface inherit
- '{' int_statements '}' semicolon_opt { $$ = type_interface_define($2, $1, $3, $5);
+required_types:
+ qualified_type { $$ = append_type(NULL, $1); }
+ | required_types ',' required_types { $$ = append_types($1, $3); }
@@ -86,26 +87,12 @@ index 01cdbffe4c7..b774b01cdd7 100644
+ | tREQUIRES required_types { $$ = $2; }
+ ;
+
+interfacedef: interfacehdr inherit requires
'{' int_statements '}' semicolon_opt { $$ = $1;
if($$ == $2)
error_loc("Interface can't inherit from itself\n");
- type_interface_define($$, $2, $4);
+ type_interface_define($$, $2, $5, $3);
+interfacedef: attributes interface inherit requires
+ '{' int_statements '}' semicolon_opt { $$ = type_interface_define($2, $1, $3, $6, $4);
check_async_uuid($$);
}
/* MIDL is able to import the definition of a base class from inside the
* definition of a derived class, I'll try to support it with this rule */
- | interfacehdr ':' aIDENTIFIER
+ | interfacehdr ':' aIDENTIFIER requires
'{' import int_statements '}'
semicolon_opt { $$ = $1;
- type_interface_define($$, find_type_or_error2($3, 0), $6);
+ type_interface_define($$, find_type_or_error2($3, 0), $7, $4);
}
| dispinterfacedef semicolon_opt { $$ = $1; }
;
@@ -1344,6 +1351,26 @@ static str_list_t *append_str(str_list_t *list, char *str)
@@ -1296,6 +1303,26 @@ static str_list_t *append_str(str_list_t *list, char *str)
return list;
}
@@ -132,66 +119,66 @@ index 01cdbffe4c7..b774b01cdd7 100644
static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
{
attr_t *attr;
@@ -3060,7 +3087,7 @@ static void check_async_uuid(type_t *iface)
@@ -2981,7 +3008,7 @@ static void check_async_uuid(type_t *iface)
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
- type_interface_define(async_iface, inherit, stmts);
+ type_interface_define(async_iface, inherit, stmts, NULL);
- type_interface_define(async_iface, map_attrs(iface->attrs, async_iface_attrs), inherit, stmts);
+ type_interface_define(async_iface, map_attrs(iface->attrs, async_iface_attrs), inherit, stmts, NULL);
iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface;
}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index a18ffe1f4a5..fa21766b253 100644
index b3f0725f00e..c67daa6ae8c 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -463,7 +463,7 @@ static unsigned int compute_method_indexes(type_t *iface)
return idx;
@@ -441,7 +441,7 @@ type_t *type_interface_declare(char *name, struct namespace *namespace)
return type;
}
-void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts)
+void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts, type_list_t *requires)
-type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts)
+type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires)
{
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
iface->details.iface->disp_props = NULL;
@@ -472,6 +472,7 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
if (iface->defined)
error_loc("interface %s already defined at %s:%d\n",
@@ -457,6 +457,7 @@ type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit
iface->details.iface->inherit = inherit;
iface->details.iface->disp_inherit = NULL;
iface->details.iface->async_iface = NULL;
+ iface->details.iface->requires = requires;
iface->defined = TRUE;
compute_method_indexes(iface);
}
@@ -486,6 +487,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
return iface;
@@ -485,6 +486,7 @@ type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t
if (!iface->details.iface->inherit) error_loc("IDispatch 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);
}
@@ -500,6 +502,7 @@ void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
return iface;
@@ -504,6 +506,7 @@ type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *att
if (!dispiface->details.iface->inherit) error_loc("IDispatch is undefined\n");
dispiface->details.iface->disp_inherit = iface;
dispiface->details.iface->async_iface = NULL;
+ dispiface->details.iface->requires = NULL;
dispiface->defined = TRUE;
compute_method_indexes(dispiface);
}
return dispiface;
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index dc44c3f5fa7..a4ba4333bae 100644
index 8e04537ab4d..b238c11f615 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -45,7 +45,7 @@ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
@@ -53,7 +53,7 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_new_runtimeclass(char *name, struct namespace *namespace);
-void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
+void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts);
@@ -170,6 +170,13 @@ static inline type_t *type_iface_get_inherit(const type_t *type)
type_t *type_runtimeclass_declare(char *name, struct namespace *namespace);
type_t *type_interface_declare(char *name, struct namespace *namespace);
-type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts);
+type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
type_t *type_dispinterface_declare(char *name);
type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t *props, var_list_t *methods);
type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *attrs, type_t *iface);
@@ -181,6 +181,13 @@ static inline type_t *type_iface_get_inherit(const type_t *type)
return type->details.iface->inherit;
}
@@ -206,10 +193,10 @@ index dc44c3f5fa7..a4ba4333bae 100644
{
type = type_get_real_type(type);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 8e9ba3e4460..7db2deb1839 100644
index facfff21453..a3000a7417b 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -385,6 +385,7 @@ struct iface_details
@@ -386,6 +386,7 @@ struct iface_details
struct _type_t *inherit;
struct _type_t *disp_inherit;
struct _type_t *async_iface;
@@ -218,5 +205,5 @@ index 8e9ba3e4460..7db2deb1839 100644
struct module_details
--
2.29.2
2.20.1

View File

@@ -1,4 +1,4 @@
From e0a0dba826b36993a81ae1df1186e53bfbe8e61c Mon Sep 17 00:00:00 2001
From ed06a9e2f0f490cd146c3fc0854f88ce59a134ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 13 Oct 2020 16:31:16 +0200
Subject: [PATCH] widl: Support WinRT parameterized type parsing.
@@ -15,16 +15,16 @@ Having these interfaces declared in the IDL, guarded with __WIDL__ ifdef
is easier and more flexible than re-creating the types by hand in WIDL
source.
---
include/windows.foundation.idl | 29 +++++++++++++++++
include/windows.foundation.idl | 29 +++++++++++++++
tools/widl/expr.c | 2 ++
tools/widl/header.c | 8 +++--
tools/widl/parser.y | 57 ++++++++++++++++++++++++++++++++--
tools/widl/parser.y | 64 ++++++++++++++++++++++++++++++----
tools/widl/typegen.c | 6 ++++
tools/widl/typelib.c | 2 ++
tools/widl/typetree.c | 30 ++++++++++++++++++
tools/widl/typetree.c | 39 +++++++++++++++++++++
tools/widl/typetree.h | 4 +++
tools/widl/widltypes.h | 9 ++++++
9 files changed, 142 insertions(+), 5 deletions(-)
tools/widl/widltypes.h | 9 +++++
9 files changed, 154 insertions(+), 9 deletions(-)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
index 5e17062f399..ab7c4753c3b 100644
@@ -79,7 +79,7 @@ index 13bd5a889aa..c83e9aa5ec0 100644
break;
case TYPE_ALIAS:
diff --git a/tools/widl/header.c b/tools/widl/header.c
index 4db244fef5d..344b6891747 100644
index e6394991317..8423756e060 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -488,6 +488,8 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
@@ -100,7 +100,7 @@ index 4db244fef5d..344b6891747 100644
/* not supposed to be here */
assert(0);
break;
@@ -1860,10 +1864,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
@@ -1864,10 +1868,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
write_apicontract(header, stmt->u.type);
else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
write_runtimeclass(header, stmt->u.type);
@@ -113,41 +113,41 @@ index 4db244fef5d..344b6891747 100644
case STMT_TYPEREF:
/* FIXME: shouldn't write out forward declarations for undefined
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index e5a39872524..9083df8cf27 100644
index 169a5ba6386..c417a3ec963 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -81,6 +81,8 @@ static var_t *reg_const(var_t *var);
@@ -78,6 +78,8 @@ static var_t *reg_const(var_t *var);
static void push_namespace(const char *name);
static void pop_namespace(const char *name);
static void push_lookup_namespace(const char *name);
+static void push_parameters_namespace(const char *name);
+static void pop_parameters_namespace(const char *name);
static void check_arg_attrs(const var_t *arg);
static void check_statements(const statement_list_t *stmts, int is_inside_library);
@@ -126,6 +128,7 @@ static struct namespace global_namespace = {
@@ -115,6 +117,7 @@ static struct namespace global_namespace = {
};
static struct namespace *current_namespace = &global_namespace;
static struct namespace *lookup_namespace = &global_namespace;
+static struct namespace *parameters_namespace = NULL;
static typelib_t *current_typelib;
@@ -297,6 +300,8 @@ static typelib_t *current_typelib;
@@ -289,6 +292,8 @@ static typelib_t *current_typelib;
%type <type> base_type int_std
%type <type> enumdef structdef uniondef typedecl
%type <type> type qualified_type
%type <type> type unqualified_type qualified_type
+%type <type> type_parameter
+%type <typelist> type_parameters
%type <typelist> requires required_types
%type <ifref> class_interface
%type <ifref_list> class_interfaces
@@ -1014,6 +1019,15 @@ interfacehdr: attributes interface { $$ = $2;
}
@@ -963,7 +968,18 @@ inherit: { $$ = NULL; }
| ':' qualified_type { $$ = $2; }
;
+type_parameter: aIDENTIFIER { $$ = get_type(TYPE_PARAMETER, $1, parameters_namespace, 0); }
+ | aKNOWNTYPE { $$ = get_type(TYPE_PARAMETER, $1, parameters_namespace, 0); }
-interface: tINTERFACE typename { $$ = type_interface_declare($2, current_namespace); }
+type_parameter: typename { $$ = get_type(TYPE_PARAMETER, $1, parameters_namespace, 0); }
+ ;
+
+type_parameters:
@@ -155,37 +155,37 @@ index e5a39872524..9083df8cf27 100644
+ | type_parameters ',' type_parameter { $$ = append_type($1, $3); }
+ ;
+
required_types:
qualified_type { $$ = append_type(NULL, $1); }
| required_types ',' required_types { $$ = append_types($1, $3); }
@@ -1029,6 +1043,13 @@ interfacedef: interfacehdr inherit requires
type_interface_define($$, $2, $5, $3);
check_async_uuid($$);
}
+ | interfacehdr '<' { push_parameters_namespace($1->name); } type_parameters '>' inherit
+ '{' int_statements '}' semicolon_opt { $$ = $1;
+ if($$ == $6) error_loc("Interface can't inherit from itself\n");
+ type_parameterized_interface_define($$, $4, $6, $8);
+ check_async_uuid($$);
+ pop_parameters_namespace($1->name);
+ }
/* MIDL is able to import the definition of a base class from inside the
* definition of a derived class, I'll try to support it with this rule */
| interfacehdr ':' aIDENTIFIER requires
@@ -1041,6 +1062,11 @@ interfacedef: interfacehdr inherit requires
interfacedec:
interface ';' { $$ = $1; }
+ | interface '<' { push_parameters_namespace($1->name); } type_parameters '>' ';'
+ { $$ = $1;
+ type_parameterized_interface_declare($$, $4);
+ pop_parameters_namespace($1->name);
+ }
| dispinterface ';' { $$ = $1; }
+interface:
+ tINTERFACE typename { $$ = type_interface_declare($2, current_namespace); }
+ | tINTERFACE typename '<' { push_parameters_namespace($2); } type_parameters { pop_parameters_namespace($2); } '>'
+ { $$ = type_parameterized_interface_declare($2, current_namespace, $5); }
;
@@ -2017,6 +2043,29 @@ static void push_lookup_namespace(const char *name)
lookup_namespace = namespace;
required_types:
@@ -974,9 +990,18 @@ requires: { $$ = NULL; }
| tREQUIRES required_types { $$ = $2; }
;
-interfacedef: attributes interface inherit requires
- '{' int_statements '}' semicolon_opt { $$ = type_interface_define($2, $1, $3, $6, $4);
- check_async_uuid($$);
+interfacedef: attributes interface { if ($2->type_type == TYPE_PARAMETERIZED_TYPE) push_parameters_namespace($2->name); }
+ inherit requires '{' int_statements '}' semicolon_opt
+ { if ($2->type_type == TYPE_PARAMETERIZED_TYPE)
+ {
+ $$ = type_parameterized_interface_define($2, $1, $4, $7, $5);
+ pop_parameters_namespace($2->name);
+ }
+ else
+ {
+ $$ = type_interface_define($2, $1, $4, $7, $5);
+ check_async_uuid($$);
+ }
}
| dispinterfacedef semicolon_opt { $$ = $1; }
;
@@ -1959,6 +1984,29 @@ static void pop_namespace(const char *name)
current_namespace = current_namespace->parent;
}
+static void push_parameters_namespace(const char *name)
@@ -214,27 +214,27 @@ index e5a39872524..9083df8cf27 100644
struct rtype {
const char *name;
type_t *type;
@@ -2148,7 +2197,8 @@ static type_t *find_qualified_type_or_error(const char *name, int t)
static type_t *find_type_or_error(const char *name, int t)
@@ -2071,7 +2119,8 @@ type_t *find_type(const char *name, struct namespace *namespace, int t)
static type_t *find_type_or_error(struct namespace *namespace, const char *name)
{
type_t *type;
- if (!(type = find_type(name, current_namespace, t)))
+ if (!(type = find_type(name, current_namespace, t)) &&
+ !(type = find_type(name, parameters_namespace, t)))
- if (!(type = find_type(name, namespace, 0)))
+ if (!(type = find_type(name, namespace, 0)) &&
+ !(type = find_type(name, parameters_namespace, 0)))
{
error_loc("type '%s' not found\n", name);
error_loc("type '%s' not found in %s namespace\n", name, namespace && namespace->name ? namespace->name : "global");
return NULL;
@@ -2168,7 +2218,8 @@ int is_type(const char *name)
if (lookup_namespace != &global_namespace)
return find_type(name, lookup_namespace, 0) != NULL;
else
- return find_type(name, current_namespace, 0) != NULL;
+ return find_type(name, current_namespace, 0) != NULL ||
+ find_type(name, parameters_namespace, 0) != NULL;
@@ -2093,7 +2142,8 @@ static struct namespace *find_namespace_or_error(struct namespace *parent, const
int is_type(const char *name)
{
- return find_type(name, current_namespace, 0) != NULL;
+ return find_type(name, current_namespace, 0) != NULL ||
+ find_type(name, parameters_namespace, 0);
}
int is_namespace(const char *name)
@@ -2666,6 +2717,8 @@ static int is_allowed_conf_type(const type_t *type)
type_t *get_type(enum type_type type, char *name, struct namespace *namespace, int t)
@@ -2585,6 +2635,8 @@ static int is_allowed_conf_type(const type_t *type)
case TYPE_RUNTIMECLASS:
return FALSE;
case TYPE_APICONTRACT:
@@ -288,33 +288,39 @@ index ace6424e3a0..6f6c5f3ccc8 100644
assert(0);
break;
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index fa21766b253..f451f8f3a1a 100644
index c67daa6ae8c..3a0934af7c5 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -463,6 +463,36 @@ static unsigned int compute_method_indexes(type_t *iface)
return idx;
@@ -594,6 +594,45 @@ type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs)
return apicontract;
}
+void type_parameterized_interface_declare(type_t *type, type_list_t *params)
+type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, type_list_t *params)
+{
+ type_t *iface = make_type(TYPE_INTERFACE);
+ type->type_type = TYPE_PARAMETERIZED_TYPE;
+ type->details.parameterized.type = iface;
+ type_t *type = get_type(TYPE_PARAMETERIZED_TYPE, name, namespace, 0);
+ if (type_get_type_detect_alias(type) != TYPE_PARAMETERIZED_TYPE)
+ error_loc("pinterface %s previously not declared a pinterface at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+ type->details.parameterized.type = make_type(TYPE_INTERFACE);
+ type->details.parameterized.params = params;
+ return type;
+}
+
+void type_parameterized_interface_define(type_t *type, type_list_t *params, type_t *inherit, statement_list_t *stmts)
+type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires)
+{
+ type_t *iface;
+
+ if (type->type_type != TYPE_PARAMETERIZED_TYPE) type_parameterized_interface_declare(type, params);
+ iface = type->details.parameterized.type;
+ if (type->defined)
+ error_loc("pinterface %s already defined at %s:%d\n",
+ type->name, type->loc_info.input_name, type->loc_info.line_number);
+
+ /* The parameterized type UUID is actually a PIID that is then used as a seed to generate
+ * a new type GUID with the rules described in:
+ * https://docs.microsoft.com/en-us/uwp/winrt-cref/winrt-type-system#parameterized-types
+ * FIXME: store type signatures for generated interfaces, and generate their GUIDs
+ * TODO: store type signatures for generated interfaces, and generate their GUIDs
+ */
+ type->attrs = check_interface_attrs(type->name, attrs);
+
+ iface = type->details.parameterized.type;
+ iface->details.iface = xmalloc(sizeof(*iface->details.iface));
+ iface->details.iface->disp_props = NULL;
+ iface->details.iface->disp_methods = NULL;
@@ -322,26 +328,29 @@ index fa21766b253..f451f8f3a1a 100644
+ iface->details.iface->inherit = inherit;
+ iface->details.iface->disp_inherit = NULL;
+ iface->details.iface->async_iface = NULL;
+ iface->details.iface->requires = NULL;
+ iface->details.iface->requires = requires;
+
+ type->defined = TRUE;
+ return type;
+}
+
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts, type_list_t *requires)
int type_is_equal(const type_t *type1, const type_t *type2)
{
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index a4ba4333bae..79c5a01ce3a 100644
index b238c11f615..fab32ff9e64 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -45,6 +45,8 @@ type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_new_runtimeclass(char *name, struct namespace *namespace);
+void type_parameterized_interface_declare(type_t *type, type_list_t *params);
+void type_parameterized_interface_define(type_t *type, type_list_t *params, type_t *inherit, statement_list_t *stmts);
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
@@ -235,6 +237,8 @@ static inline int type_is_complete(const type_t *type)
@@ -62,6 +62,8 @@ type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *i
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_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_parameterized_interface_declare(char *name, struct namespace *namespace, type_list_t *params);
+type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
int type_is_equal(const type_t *type1, const type_t *type2);
const char *type_get_name(const type_t *type, enum name_type name_type);
char *gen_name(void);
@@ -246,6 +248,8 @@ static inline int type_is_complete(const type_t *type)
case TYPE_RUNTIMECLASS:
return TRUE;
case TYPE_APICONTRACT:
@@ -385,5 +394,5 @@ index a3000a7417b..2c0ac4003ce 100644
const char *c_name;
unsigned int typestring_offset;
--
2.29.2
2.20.1

View File

@@ -0,0 +1,309 @@
From ef2cb861ce5a9d47ecc10e337a192a3de32dbda3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 1 Dec 2020 14:41:01 +0100
Subject: [PATCH] widl: Introduce new strappend helper.
And use it for format_namespace to grow buffer as needed.
---
include/windows.foundation.idl | 9 +++++
tools/widl/parser.y | 35 ++++++++++++++++
tools/widl/typetree.c | 73 +++++++++++++++++++++-------------
tools/widl/typetree.h | 3 ++
tools/widl/utils.c | 37 +++++++++++++++++
tools/widl/utils.h | 1 +
tools/widl/widltypes.h | 1 +
7 files changed, 132 insertions(+), 27 deletions(-)
diff --git a/include/windows.foundation.idl b/include/windows.foundation.idl
index ab7c4753c3b..5f7a49c38e4 100644
--- a/include/windows.foundation.idl
+++ b/include/windows.foundation.idl
@@ -127,6 +127,15 @@ namespace Windows {
HRESULT GetMany([in] UINT32 count, [out] T *items, [out, retval] UINT32 *value);
}
+ [
+ contract(Windows.Foundation.FoundationContract, 1.0),
+ uuid(faa585ea-6214-4217-afda-7f46de5869b3)
+ ]
+ interface IIterable<T> : IInspectable
+ {
+ HRESULT First([out, retval] Windows.Foundation.Collections.IIterator<T> **value);
+ }
+
[
contract(Windows.Foundation.FoundationContract, 1.0),
uuid(bbe1fa4c-b0e3-4583-baef-1f1b2e483e56)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index c417a3ec963..92f6345e2dc 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -294,6 +294,8 @@ static typelib_t *current_typelib;
%type <type> type unqualified_type qualified_type
%type <type> type_parameter
%type <typelist> type_parameters
+%type <type> parameterized_type
+%type <typelist> parameterized_types
%type <typelist> requires required_types
%type <ifref> class_interface
%type <ifref_list> class_interfaces
@@ -910,6 +912,20 @@ qualified_type:
| namespace_pfx typename { $$ = find_type_or_error($1, $2); }
;
+parameterized_type: qualified_type '<' parameterized_types '>'
+ { $$ = find_parameterized_type($1, $3); }
+ ;
+
+parameterized_types:
+ base_type { $$ = append_type(NULL, $1); }
+ | qualified_type { $$ = append_type(NULL, $1); }
+ | qualified_type '*' { $$ = append_type(NULL, type_new_pointer($1)); }
+ | parameterized_type { $$ = append_type(NULL, $1); }
+ | parameterized_type '*' { $$ = append_type(NULL, type_new_pointer($1)); }
+ | parameterized_types ',' parameterized_types
+ { $$ = append_types($1, $3); }
+ ;
+
coclass: tCOCLASS typename { $$ = type_coclass_declare($2); }
;
@@ -966,6 +982,7 @@ dispinterfacedef:
inherit: { $$ = NULL; }
| ':' qualified_type { $$ = $2; }
+ | ':' parameterized_type { $$ = $2; }
;
type_parameter: typename { $$ = get_type(TYPE_PARAMETER, $1, parameters_namespace, 0); }
@@ -984,6 +1001,7 @@ interface:
required_types:
qualified_type { $$ = append_type(NULL, $1); }
+ | parameterized_type { $$ = append_type(NULL, $1); }
| required_types ',' required_types { $$ = append_types($1, $3); }
requires: { $$ = NULL; }
@@ -1208,6 +1226,7 @@ unqualified_type:
type:
unqualified_type
| namespace_pfx typename { $$ = find_type_or_error($1, $2); }
+ | parameterized_type { $$ = $1; }
;
typedef: m_attributes tTYPEDEF m_attributes decl_spec declarator_list
@@ -3279,3 +3298,19 @@ void init_loc_info(loc_info_t *i)
i->line_number = line_number;
i->near_text = parser_text;
}
+
+type_t *find_parameterized_type(type_t *type, type_list_t *params)
+{
+ char *name = format_parameterized_type_name(type, params);
+
+ if (parameters_namespace)
+ {
+ assert(type->type_type == TYPE_PARAMETERIZED_TYPE);
+ type = type_parameterized_type_specialize_partial(type, params);
+ }
+ /* FIXME: If not in another parameterized type, we'll have to look for the declared specialization. */
+ else error_loc("parameterized type '%s' not declared\n", name);
+
+ free(name);
+ return type;
+}
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
index 3a0934af7c5..1a5b13add96 100644
--- a/tools/widl/typetree.c
+++ b/tools/widl/typetree.c
@@ -89,41 +89,52 @@ const char *type_get_name(const type_t *type, enum name_type name_type)
return NULL;
}
-static char *append_namespace(char *ptr, struct namespace *namespace, const char *separator, const char *abi_prefix)
+static size_t append_namespace(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *separator, const char *abi_prefix)
{
- if(is_global_namespace(namespace)) {
- if(!abi_prefix) return ptr;
- strcpy(ptr, abi_prefix);
- strcat(ptr, separator);
- return ptr + strlen(ptr);
- }
-
- ptr = append_namespace(ptr, namespace->parent, separator, abi_prefix);
- strcpy(ptr, namespace->name);
- strcat(ptr, separator);
- return ptr + strlen(ptr);
+ int nested = namespace && !is_global_namespace(namespace);
+ const char *name = nested ? namespace->name : abi_prefix;
+ size_t n = 0;
+ if (!name) return 0;
+ if (nested) n += append_namespace(buf, len, pos + n, namespace->parent, separator, abi_prefix);
+ n += strappend(buf, len, pos + n, "%s%s", name, separator);
+ return n;
}
-char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
- const char *abi_prefix)
+static size_t append_namespaces(char **buf, size_t *len, size_t pos, struct namespace *namespace, const char *prefix,
+ const char *separator, const char *suffix, const char *abi_prefix)
{
- unsigned len = strlen(prefix) + strlen(suffix);
- unsigned sep_len = strlen(separator);
- struct namespace *iter;
- char *ret, *ptr;
+ size_t n = 0;
+ n += strappend(buf, len, pos + n, "%s", prefix);
+ n += append_namespace(buf, len, pos + n, namespace, separator, abi_prefix);
+ n += strappend(buf, len, pos + n, "%s", suffix);
+ return n;
+}
- if(abi_prefix)
- len += strlen(abi_prefix) + sep_len;
+char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix)
+{
+ size_t len = 0;
+ char *buf = NULL;
+ append_namespaces(&buf, &len, 0, namespace, prefix, separator, suffix, abi_prefix);
+ return buf;
+}
- for(iter = namespace; !is_global_namespace(iter); iter = iter->parent)
- len += strlen(iter->name) + sep_len;
+char *format_parameterized_type_name(type_t *type, type_list_t *params)
+{
+ size_t len = 0, pos = 0;
+ char *buf = NULL;
+ type_list_t *entry;
- ret = xmalloc(len+1);
- strcpy(ret, prefix);
- ptr = append_namespace(ret + strlen(ret), namespace, separator, abi_prefix);
- strcpy(ptr, suffix);
+ pos += strappend(&buf, &len, pos, "%s<", type->name);
+ for (entry = params; entry; entry = entry->next)
+ {
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) {}
+ pos += append_namespaces(&buf, &len, pos, type->namespace, "", "::", type->name, use_abi_namespace ? "ABI" : NULL);
+ for (type = entry->type; type->type_type == TYPE_POINTER; type = type_pointer_get_ref_type(type)) pos += strappend(&buf, &len, pos, "*");
+ if (entry->next) pos += strappend(&buf, &len, pos, ",");
+ }
+ pos += strappend(&buf, &len, pos, ">");
- return ret;
+ return buf;
}
type_t *type_new_function(var_list_t *args)
@@ -633,6 +644,14 @@ type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, ty
return type;
}
+type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params)
+{
+ type_t *new_type = duptype(type, 0);
+ new_type->details.parameterized.type = type;
+ new_type->details.parameterized.params = params;
+ return new_type;
+}
+
int type_is_equal(const type_t *type1, const type_t *type2)
{
if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index fab32ff9e64..538134871a2 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -36,6 +36,8 @@ attr_list_t *check_interface_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs);
+type_t *find_parameterized_type(type_t *type, type_list_t *params);
+
type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(type_t *ref);
type_t *type_new_alias(const decl_spec_t *t, const char *name);
@@ -64,6 +66,7 @@ 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_parameterized_interface_declare(char *name, struct namespace *namespace, type_list_t *params);
type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, type_list_t *requires);
+type_t *type_parameterized_type_specialize_partial(type_t *type, type_list_t *params);
int type_is_equal(const type_t *type1, const type_t *type2);
const char *type_get_name(const type_t *type, enum name_type name_type);
char *gen_name(void);
diff --git a/tools/widl/utils.c b/tools/widl/utils.c
index ea92372c8c7..634bd12a0ba 100644
--- a/tools/widl/utils.c
+++ b/tools/widl/utils.c
@@ -245,6 +245,43 @@ char *strmake( const char* fmt, ... )
}
}
+size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...)
+{
+ size_t size;
+ va_list ap;
+ char *ptr;
+ int n;
+
+ assert( buf && len );
+ assert( (*len == 0 && *buf == NULL) || (*len != 0 && *buf != NULL) );
+
+ if (*buf)
+ {
+ size = *len;
+ ptr = *buf;
+ }
+ else
+ {
+ size = 100;
+ ptr = xmalloc( size );
+ }
+
+ for (;;)
+ {
+ va_start( ap, fmt );
+ n = vsnprintf( ptr + pos, size - pos, fmt, ap );
+ va_end( ap );
+ if (n == -1) size *= 2;
+ else if (pos + (size_t)n >= size) size = pos + n + 1;
+ else break;
+ ptr = xrealloc( ptr, size );
+ }
+
+ *len = size;
+ *buf = ptr;
+ return n;
+}
+
char *xstrdup(const char *str)
{
char *s;
diff --git a/tools/widl/utils.h b/tools/widl/utils.h
index 37406656504..82e0a6ae489 100644
--- a/tools/widl/utils.h
+++ b/tools/widl/utils.h
@@ -45,6 +45,7 @@ void warning(const char *s, ...) __attribute__((format (printf, 1, 2)));
void warning_loc_info(const loc_info_t *, const char *s, ...) __attribute__((format (printf, 2, 3)));
void chat(const char *s, ...) __attribute__((format (printf, 1, 2)));
char *strmake(const char* fmt, ...) __attribute__((__format__ (__printf__, 1, 2 )));
+size_t strappend(char **buf, size_t *len, size_t pos, const char* fmt, ...) __attribute__((__format__ (__printf__, 4, 5 )));
char *dup_basename(const char *name, const char *ext);
size_t widl_getline(char **linep, size_t *lenp, FILE *fp);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 2c0ac4003ce..be82342e31a 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -650,6 +650,7 @@ void init_loc_info(loc_info_t *);
char *format_namespace(struct namespace *namespace, const char *prefix, const char *separator, const char *suffix,
const char *abi_prefix);
+char *format_parameterized_type_name(type_t *type, type_list_t *params);
static inline enum type_type type_get_type_detect_alias(const type_t *type)
{
--
2.20.1

Some files were not shown because too many files have changed in this diff Show More