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 73b3b97a821..2ab12abe377 100644 --- a/tools/widl/metadata.c +++ b/tools/widl/metadata.c @@ -1910,6 +1910,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[256 + 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; @@ -1950,6 +1995,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 ); } }
@@ -2115,8 +2162,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];
@@ -2126,7 +2182,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 ) @@ -2155,7 +2211,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, };