[PATCH 5/6] widl: Implement initial support for generics.
Rémi Bernon
rbernon at codeweavers.com
Wed Aug 26 17:57:09 CDT 2020
This should be enough to add the UWP dll stubs in idl files, but it's
casting generics to void*. MIDL does something different apparently
and even generates a new interface for every parameter type.
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
tools/widl/expr.c | 1 +
tools/widl/header.c | 4 ++++
tools/widl/parser.y | 27 +++++++++++++++++++++++----
tools/widl/typegen.c | 4 ++++
tools/widl/typelib.c | 1 +
tools/widl/typetree.h | 1 +
tools/widl/widltypes.h | 1 +
7 files changed, 35 insertions(+), 4 deletions(-)
diff --git a/tools/widl/expr.c b/tools/widl/expr.c
index d1ee599a39e..950a1e46b6f 100644
--- a/tools/widl/expr.c
+++ b/tools/widl/expr.c
@@ -460,6 +460,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
case TYPE_COCLASS:
case TYPE_INTERFACE:
case TYPE_POINTER:
+ case TYPE_GENERIC:
case TYPE_ARRAY:
case TYPE_BITFIELD:
/* nothing to do */
diff --git a/tools/widl/header.c b/tools/widl/header.c
index ff4fb4bc210..856cec9da05 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -454,6 +454,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
case TYPE_COCLASS:
fprintf(h, "%s", name);
break;
+ case TYPE_GENERIC:
+ fprintf(h, "void*/*%s*/", name);
+ break;
case TYPE_VOID:
fprintf(h, "void");
break;
@@ -519,6 +522,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_BITFIELD:
fprintf(h, " : %u", type_bitfield_get_bits(t)->cval);
break;
+ case TYPE_GENERIC:
case TYPE_VOID:
case TYPE_BASIC:
case TYPE_ENUM:
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index d0883f7b8ab..1ca1ecb23c7 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -274,7 +274,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_seq qualified_type generics_type generics_decl
%type <ifref> coclass_int
%type <ifref_list> coclass_ints
%type <var> arg ne_union_field union_field s_field case enum declaration
@@ -830,6 +830,11 @@ qualified_type:
| aNAMESPACE '.' { init_lookup_namespace($1); } qualified_seq { $$ = $4; }
;
+generics_list: generics_type | generics_type '*' | generics_list ',' generics_list;
+generics_args: | '<' generics_list '>';
+
+generics_type: qualified_type generics_args;
+
coclass: tCOCLASS aIDENTIFIER { $$ = type_new_coclass($2); }
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0);
if (type_get_type_detect_alias($$) != TYPE_COCLASS)
@@ -895,13 +900,16 @@ dispinterfacedef: dispinterfacehdr '{'
;
inherit: { $$ = NULL; }
- | ':' qualified_type { $$ = $2; }
+ | ':' generics_type { $$ = $2; }
;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
| tINTERFACE aKNOWNTYPE { $$ = get_type(TYPE_INTERFACE, $2, current_namespace, 0); }
;
+generics_decl: aIDENTIFIER { $$ = get_type(TYPE_GENERIC, $1, current_namespace, 0); };
+generics_decls: generics_decl | generics_decls ',' generics_decls;
+
interfacehdr: attributes interface { $$ = $2;
check_def($2);
$2->attrs = check_iface_attrs($2->name, $1);
@@ -923,11 +931,21 @@ interfacedef: interfacehdr inherit
semicolon_opt { $$ = $1;
type_interface_define($$, find_type_or_error2($3, 0), $6);
}
+ | interfacehdr
+ '<' { push_namespace($1->name); } generics_decls '>' inherit
+ '{' int_statements '}' semicolon_opt
+ {
+ $$ = $1;
+ if($$ == $6) error_loc("Interface can't inherit from itself\n");
+ type_interface_define($$, $6, $8);
+ check_async_uuid($$);
+ pop_namespace($1->name);
+ }
| dispinterfacedef semicolon_opt { $$ = $1; }
;
interfacedec:
- interface ';' { $$ = $1; }
+ interface generics_args ';' { $$ = $1; }
| dispinterface ';' { $$ = $1; }
;
@@ -1110,7 +1128,7 @@ structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_nam
;
type: tVOID { $$ = type_new_void(); }
- | qualified_type { $$ = $1; }
+ | generics_type { $$ = $1; }
| base_type { $$ = $1; }
| enumdef { $$ = $1; }
| tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
@@ -2431,6 +2449,7 @@ static int is_allowed_conf_type(const type_t *type)
case TYPE_ENCAPSULATED_UNION:
case TYPE_ARRAY:
case TYPE_POINTER:
+ case TYPE_GENERIC:
case TYPE_VOID:
case TYPE_MODULE:
case TYPE_COCLASS:
diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c
index 04280cbb722..f872e039010 100644
--- a/tools/widl/typegen.c
+++ b/tools/widl/typegen.c
@@ -351,6 +351,8 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
(is_attr(attrs, ATTR_RANGE) || is_aliaschain_attr(type, ATTR_RANGE)))
return TGT_RANGE;
return TGT_ENUM;
+ case TYPE_GENERIC:
+ return TGT_IFACE_POINTER;
case TYPE_POINTER:
if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
(type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
@@ -1936,6 +1938,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
size = union_memsize(type_union_get_cases(t), align);
break;
case TYPE_POINTER:
+ case TYPE_GENERIC:
case TYPE_INTERFACE:
assert( pointer_size );
size = pointer_size;
@@ -2060,6 +2063,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
/* else fall through */
case TYPE_POINTER:
return 4;
+ case TYPE_GENERIC:
case TYPE_INTERFACE:
case TYPE_ALIAS:
case TYPE_VOID:
diff --git a/tools/widl/typelib.c b/tools/widl/typelib.c
index cf027558d0a..060ef45218a 100644
--- a/tools/widl/typelib.c
+++ b/tools/widl/typelib.c
@@ -193,6 +193,7 @@ unsigned short get_type_vt(type_t *t)
break;
case TYPE_POINTER:
+ case TYPE_GENERIC:
return VT_PTR;
case TYPE_ARRAY:
diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
index e288c574002..6afa5d25fe5 100644
--- a/tools/widl/typetree.h
+++ b/tools/widl/typetree.h
@@ -220,6 +220,7 @@ static inline int type_is_complete(const type_t *type)
case TYPE_MODULE:
case TYPE_COCLASS:
case TYPE_POINTER:
+ case TYPE_GENERIC:
case TYPE_ARRAY:
case TYPE_BITFIELD:
return TRUE;
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h
index 1634f9bd50b..47704ce7d34 100644
--- a/tools/widl/widltypes.h
+++ b/tools/widl/widltypes.h
@@ -432,6 +432,7 @@ enum type_type
TYPE_POINTER,
TYPE_ARRAY,
TYPE_BITFIELD,
+ TYPE_GENERIC,
};
struct _type_t {
--
2.28.0
More information about the wine-devel
mailing list