-- v4: widl: Add rows for the deprecated attribute. widl: Add rows for the default_overload attribute. widl: Add rows for the overload attribute. widl: Use a define for maximum name length.
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 73b3b97a821..dc15704e2a7 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1394,6 +1394,8 @@ enum #define MODULE_ROW 1 #define MSCORLIB_ROW 1
+#define MAX_NAME 256 + static UINT add_name( type_t *type, UINT *namespace ) { UINT name = add_string( type->name ); @@ -1672,7 +1674,7 @@ static void add_contract_attr_step1( type_t *type ) static void add_contract_attr_step2( type_t *type ) { UINT parent, attr_type, value_size; - BYTE value[256 + sizeof(UINT) + 5]; + BYTE value[MAX_NAME + sizeof(UINT) + 5];
if (!is_attr( type->attrs, ATTR_CONTRACT )) return;
@@ -1900,7 +1902,7 @@ static void add_exclusiveto_attr_step1( type_t *type ) static void add_exclusiveto_attr_step2( type_t *type ) { UINT parent, attr_type, value_size; - BYTE value[256 + 5]; + BYTE value[MAX_NAME + 5];
if (!is_attr( type->attrs, ATTR_EXCLUSIVETO )) return;
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 64 ++++++++++++++++++++++++++++++++++++++++-- tools/widl/widltypes.h | 1 + 2 files changed, 62 insertions(+), 3 deletions(-)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index dc15704e2a7..5f13e6b315c 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1912,6 +1912,51 @@ static void add_exclusiveto_attr_step2( type_t *type ) add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); }
+static UINT make_overload_value( const var_t *method, BYTE *buf ) +{ + UINT len = strlen( method->name ); + + buf[0] = 1; + buf[1] = 0; + buf[2] = len; + memcpy( buf + 3, method->name, len ); + len += 3; + buf[len++] = 0; + buf[len++] = 0; + + return len; +} + +static void add_overload_attr_step1( const var_t *method ) +{ + static const BYTE sig[] = { SIG_TYPE_HASTHIS, 1, ELEMENT_TYPE_VOID, ELEMENT_TYPE_STRING }; + UINT assemblyref, scope, typeref, class; + type_t *type = method->declspec.type; + + if (!is_attr( method->attrs, ATTR_OVERLOAD )) return; + + assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") ); + scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref ); + typeref = add_typeref_row( scope, add_string("OverloadAttribute"), add_string("Windows.Foundation.Metadata") ); + + class = memberref_parent( TABLE_TYPEREF, typeref ); + type->md.member[MD_ATTR_OVERLOAD] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) ); +} + +static void add_overload_attr_step2( const var_t *method ) +{ + const type_t *type = method->declspec.type; + UINT parent, attr_type, value_size; + BYTE value[MAX_NAME + 5]; + + if (!is_attr( method->attrs, ATTR_OVERLOAD )) return; + + parent = has_customattribute( TABLE_METHODDEF, type->md.def ); + attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_OVERLOAD] ); + value_size = make_overload_value( method, value ); + add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); +} + static void add_method_params_step1( var_list_t *arg_list ) { var_t *arg; @@ -1952,6 +1997,8 @@ static void add_interface_type_step1( type_t *type ) const var_t *method = stmt->u.var;
add_method_params_step1( type_function_get_args(method->declspec.type) ); + + add_overload_attr_step1( method ); } }
@@ -2117,8 +2164,17 @@ static void add_eventremove_method( const type_t *iface, const var_t *method ) add_methodsemantics_row( METHOD_SEM_REMOVEON, methoddef, has_semantics(TABLE_EVENT, event) ); }
-static void add_method( const type_t *iface, const var_t *method ) +static const char *get_method_name( const var_t *method ) { + const char *name = get_attrp( method->attrs, ATTR_OVERLOAD ); + if (name) return name; + return method->name; +} + +static void add_method( const var_t *method ) +{ + const char *name = get_method_name( method ); + type_t *type = method->declspec.type; UINT paramlist, sig_size, attrs; BYTE sig[256];
@@ -2128,7 +2184,7 @@ static void add_method( const type_t *iface, const var_t *method ) attrs = METHOD_ATTR_PUBLIC | METHOD_ATTR_VIRTUAL | METHOD_ATTR_HIDEBYSIG | METHOD_ATTR_NEWSLOT | METHOD_ATTR_ABSTRACT;
- add_methoddef_row( 0, attrs, add_string(method->name), add_blob(sig, sig_size), paramlist ); + type->md.def = add_methoddef_row( 0, attrs, add_string(name), add_blob(sig, sig_size), paramlist ); }
static void add_interface_type_step2( type_t *type ) @@ -2157,7 +2213,9 @@ static void add_interface_type_step2( type_t *type ) else if (is_attr( method->attrs, ATTR_PROPPUT )) add_propput_method( type, method ); else if (is_attr( method->attrs, ATTR_EVENTADD )) add_eventadd_method( type, method ); else if (is_attr( method->attrs, ATTR_EVENTREMOVE )) add_eventremove_method( type, method ); - else add_method( type, method ); + else add_method( method ); + + add_overload_attr_step2( method ); }
add_contract_attr_step2( type ); diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 73d593a6aee..c0a31679c69 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -509,6 +509,7 @@ enum MD_ATTR_ACTIVATABLE, MD_ATTR_THREADING, MD_ATTR_MARSHALINGBEHAVIOR, + MD_ATTR_OVERLOAD, MD_ATTR_MAX, };
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 31 +++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 32 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index 5f13e6b315c..b9fd30da386 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1957,6 +1957,35 @@ static void add_overload_attr_step2( const var_t *method ) add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); }
+static void add_default_overload_attr_step1( const var_t *method ) +{ + static const BYTE sig[] = { SIG_TYPE_HASTHIS, 0, ELEMENT_TYPE_VOID }; + UINT assemblyref, scope, typeref, class; + type_t *type = method->declspec.type; + + if (!is_attr( method->attrs, ATTR_DEFAULT_OVERLOAD ) || !is_attr( method->attrs, ATTR_OVERLOAD )) return; + + assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") ); + scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref ); + typeref = add_typeref_row( scope, add_string("DefaultOverloadAttribute"), add_string("Windows.Foundation.Metadata") ); + + class = memberref_parent( TABLE_TYPEREF, typeref ); + type->md.member[MD_ATTR_DEFAULT_OVERLOAD] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sizeof(sig)) ); +} + +static void add_default_overload_attr_step2( const var_t *method ) +{ + static const BYTE value[] = { 0x01, 0x00, 0x00, 0x00 }; + const type_t *type = method->declspec.type; + UINT parent, attr_type; + + if (!is_attr( method->attrs, ATTR_DEFAULT_OVERLOAD ) || !is_attr( method->attrs, ATTR_OVERLOAD )) return; + + parent = has_customattribute( TABLE_METHODDEF, type->md.def ); + attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_DEFAULT_OVERLOAD] ); + add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) ); +} + static void add_method_params_step1( var_list_t *arg_list ) { var_t *arg; @@ -1999,6 +2028,7 @@ static void add_interface_type_step1( type_t *type ) add_method_params_step1( type_function_get_args(method->declspec.type) );
add_overload_attr_step1( method ); + add_default_overload_attr_step1( method ); } }
@@ -2215,6 +2245,7 @@ static void add_interface_type_step2( type_t *type ) else if (is_attr( method->attrs, ATTR_EVENTREMOVE )) add_eventremove_method( type, method ); else add_method( method );
+ add_default_overload_attr_step2( method ); add_overload_attr_step2( method ); }
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index c0a31679c69..307c8ed3379 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -510,6 +510,7 @@ enum MD_ATTR_THREADING, MD_ATTR_MARSHALINGBEHAVIOR, MD_ATTR_OVERLOAD, + MD_ATTR_DEFAULT_OVERLOAD, MD_ATTR_MAX, };
From: Hans Leidekker hans@codeweavers.com
--- tools/widl/metadata.c | 89 ++++++++++++++++++++++++++++++++++++++++++ tools/widl/widltypes.h | 1 + 2 files changed, 90 insertions(+)
diff --git a/tools/widl/metadata.c b/tools/widl/metadata.c index b9fd30da386..9c8eee770ab 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1618,6 +1618,22 @@ static UINT make_property_sig( const var_t *method, BYTE *buf ) return len; }
+static UINT make_deprecated_sig( UINT token, BYTE *buf ) +{ + UINT len = 5; + + buf[0] = SIG_TYPE_HASTHIS; + buf[1] = 4; + buf[2] = ELEMENT_TYPE_VOID; + buf[3] = ELEMENT_TYPE_STRING; + buf[4] = ELEMENT_TYPE_VALUETYPE; + len += encode_int( token, buf + 5 ); + buf[len++] = ELEMENT_TYPE_U4; + buf[len++] = ELEMENT_TYPE_STRING; + + return len; +} + static UINT make_contract_value( const type_t *type, BYTE *buf ) { const expr_t *contract = get_attrp( type->attrs, ATTR_CONTRACT ); @@ -1986,6 +2002,77 @@ static void add_default_overload_attr_step2( const var_t *method ) add_customattribute_row( parent, attr_type, add_blob(value, sizeof(value)) ); }
+static UINT make_deprecated_value( const var_t *method, BYTE **ret_buf ) +{ + static const BYTE zero[] = { 0x00, 0x00, 0x00, 0x00 }, one[] = { 0x01, 0x00, 0x00, 0x00 }; + const expr_t *attr = get_attrp( method->attrs, ATTR_DEPRECATED ); + const char *text = attr->ref->u.sval; + const char *kind = attr->u.ext->u.sval; + BYTE encoded[4]; + UINT len, len_text = strlen( text ), len_encoded = encode_int( len_text, encoded ); + BYTE *buf = xmalloc( 2 + len_encoded + len_text + 6 + MAX_NAME + 5 ); + char *contract; + + buf[0] = 1; + buf[1] = 0; + memcpy( buf + 2, encoded, len_encoded ); + len = 2 + len_encoded; + memcpy( buf + len, text, len_text ); + len += len_text; + if (!strcmp( kind, "remove" )) memcpy( buf + len, one, sizeof(one) ); + else memcpy( buf + len, zero, sizeof(zero) ); + len += 4; + buf[len++] = 0; + buf[len++] = 0; + + buf[len++] = 1; + buf[len++] = 0; + contract = format_namespace( attr->ext2->u.tref.type->namespace, "", ".", attr->ext2->u.tref.type->name, NULL ); + len_text = strlen( contract ); + buf[len++] = len_text; + memcpy( buf + len, contract, len_text ); + free( contract ); + len += len_text; + buf[len++] = 0; + buf[len++] = 0; + + *ret_buf = buf; + return len; +} + +static void add_deprecated_attr_step1( const var_t *method ) +{ + UINT assemblyref, scope, typeref_type, typeref, class, sig_size; + type_t *type = method->declspec.type; + BYTE sig[32]; + + if (!is_attr( method->attrs, ATTR_DEPRECATED )) return; + + assemblyref = add_assemblyref_row( 0x200, 0, add_string("Windows.Foundation") ); + scope = resolution_scope( TABLE_ASSEMBLYREF, assemblyref ); + typeref_type = add_typeref_row( scope, add_string("DeprecationType"), add_string("Windows.Foundation.Metadata") ); + typeref = add_typeref_row( scope, add_string("DeprecatedAttribute"), add_string("Windows.Foundation.Metadata") ); + + sig_size = make_deprecated_sig( typedef_or_ref(TABLE_TYPEREF, typeref_type), sig ); + class = memberref_parent( TABLE_TYPEREF, typeref ); + type->md.member[MD_ATTR_DEPRECATED] = add_memberref_row( class, add_string(".ctor"), add_blob(sig, sig_size) ); +} + +static void add_deprecated_attr_step2( const var_t *method ) +{ + const type_t *type = method->declspec.type; + UINT parent, attr_type, value_size; + BYTE *value; + + if (!is_attr( method->attrs, ATTR_DEPRECATED )) return; + + parent = has_customattribute( TABLE_METHODDEF, type->md.def ); + attr_type = customattribute_type( TABLE_MEMBERREF, type->md.member[MD_ATTR_DEPRECATED] ); + value_size = make_deprecated_value( method, &value ); + add_customattribute_row( parent, attr_type, add_blob(value, value_size) ); + free( value ); +} + static void add_method_params_step1( var_list_t *arg_list ) { var_t *arg; @@ -2029,6 +2116,7 @@ static void add_interface_type_step1( type_t *type )
add_overload_attr_step1( method ); add_default_overload_attr_step1( method ); + add_deprecated_attr_step1( method ); } }
@@ -2245,6 +2333,7 @@ static void add_interface_type_step2( type_t *type ) else if (is_attr( method->attrs, ATTR_EVENTREMOVE )) add_eventremove_method( type, method ); else add_method( method );
+ add_deprecated_attr_step2( method ); add_default_overload_attr_step2( method ); add_overload_attr_step2( method ); } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 307c8ed3379..c4e9a641ef4 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -511,6 +511,7 @@ enum MD_ATTR_MARSHALINGBEHAVIOR, MD_ATTR_OVERLOAD, MD_ATTR_DEFAULT_OVERLOAD, + MD_ATTR_DEPRECATED, MD_ATTR_MAX, };
On Fri Jun 20 07:33:29 2025 +0000, Hans Leidekker wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/8375/diffs?diff_id=187276&start_sha=6eea79c73412578e065e60c35924b1e97cfc7b8f#f49663b3e534c4786aa268c34b6d635b3be9355d_1964_1966)
It's not entirely arbitrary, names are limited to 256 characters and prefix + suffix add another 5 bytes. I added a define for maximum name length which hopefully makes that more clear.
On Thu Jun 19 19:42:07 2025 +0000, Rémi Bernon wrote:
A particular reason this goes in reverse order from step1?
midlrt adds the attributes in this order. It's strange because the other types have them in the same order but I prefer to follow midlrt here because it makes it easier to verify that we produce equivalent rows.
This merge request was approved by Rémi Bernon.
This merge request was approved by Huw Davies.