[PATCH 1/2] widl: Clarify declaration type names vs (reference) type names.

Rémi Bernon rbernon at codeweavers.com
Tue Mar 23 19:13:05 CDT 2021


On 3/23/21 9:10 PM, Rémi Bernon wrote:
> Declaration type names prefer unqualified names whereas reference type
> names prefer fully qualified names.
> 
> This also skips the enum / struct / union type prefix in WinRT mode,
> when writing C++ interfaces.
> 
> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> ---
> 
> This also fixes issues with C++ code, when some interface uses a type
> from another namespace. Currently widl isn't using qualified names for
> C++ interfaces although it should.
> 
> It's not as clean as I'd like it to be, but I think write_type_left is
> used in too many places and in too many different contexts to have a
> clean fix without undergoing a big refactor.
> 
> The "winrt_mode && name_type == NAME_DEFAULT" condition in particular
> only matches C++ generated code in WinRT, because WinRT doesn't support
> most other cases where NAME_DEFAULT is used, but it's a pretty ugly.
> 
>   tools/widl/header.c   | 18 +++++++++++-------
>   tools/widl/typetree.c |  8 ++++----
>   tools/widl/typetree.h |  2 +-
>   3 files changed, 16 insertions(+), 12 deletions(-)
> 
> diff --git a/tools/widl/header.c b/tools/widl/header.c
> index a5e5d6c6fb3..89e0ddf436e 100644
> --- a/tools/widl/header.c
> +++ b/tools/widl/header.c
> @@ -342,11 +342,12 @@ static void write_pointer_left(FILE *h, type_t *ref)
>   void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly, int write_callconv)
>   {
>     type_t *t = ds->type;
> -  const char *name;
> +  const char *decl_name, *name;
>     char *args;
>   
>     if (!h) return;
>   
> +  decl_name = type_get_decl_name(t, name_type);
>     name = type_get_name(t, name_type);
>   
>     if (ds->func_specifier & FUNCTION_SPECIFIER_INLINE)
> @@ -361,7 +362,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
>         case TYPE_ENUM:
>           if (!declonly && !t->written) {
>             assert(t->defined);
> -          if (name) fprintf(h, "enum %s {\n", name);
> +          if (decl_name) fprintf(h, "enum %s {\n", decl_name);
>             else fprintf(h, "enum {\n");
>             t->written = TRUE;
>             indentation++;
> @@ -369,13 +370,14 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
>             indent(h, -1);
>             fprintf(h, "}");
>           }
> +        else if (winrt_mode && name_type == NAME_DEFAULT && name) fprintf(h, "%s", name);
>           else fprintf(h, "enum %s", name ? name : "");
>           break;
>         case TYPE_STRUCT:
>         case TYPE_ENCAPSULATED_UNION:
>           if (!declonly && !t->written) {
>             assert(t->defined);
> -          if (name) fprintf(h, "struct %s {\n", name);
> +          if (decl_name) fprintf(h, "struct %s {\n", decl_name);
>             else fprintf(h, "struct {\n");
>             t->written = TRUE;
>             indentation++;
> @@ -386,12 +388,13 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
>             indent(h, -1);
>             fprintf(h, "}");
>           }
> +        else if (winrt_mode && name_type == NAME_DEFAULT && name) fprintf(h, "%s", name);
>           else fprintf(h, "struct %s", name ? name : "");
>           break;
>         case TYPE_UNION:
>           if (!declonly && !t->written) {
>             assert(t->defined);
> -          if (t->name) fprintf(h, "union %s {\n", t->name);
> +          if (decl_name) fprintf(h, "union %s {\n", decl_name);
>             else fprintf(h, "union {\n");
>             t->written = TRUE;
>             indentation++;
> @@ -399,7 +402,8 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
>             indent(h, -1);
>             fprintf(h, "}");
>           }
> -        else fprintf(h, "union %s", t->name ? t->name : "");
> +        else if (winrt_mode && name_type == NAME_DEFAULT && name) fprintf(h, "%s", name);
> +        else fprintf(h, "union %s", name ? name : "");
>           break;
>         case TYPE_POINTER:
>         {
> @@ -485,13 +489,13 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
>         case TYPE_INTERFACE:
>         case TYPE_MODULE:
>         case TYPE_COCLASS:
> -        fprintf(h, "%s", type_get_qualified_name(t, name_type));
> +        fprintf(h, "%s", type_get_name(t, name_type));
>           break;
>         case TYPE_RUNTIMECLASS:
>           fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t, TRUE), name_type));
>           break;
>         case TYPE_DELEGATE:
> -        fprintf(h, "%s", type_get_qualified_name(type_delegate_get_iface(t), name_type));
> +        fprintf(h, "%s", type_get_name(type_delegate_get_iface(t), name_type));
>           break;
>         case TYPE_VOID:
>           fprintf(h, "void");
> diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c
> index a4e1696d2af..c9daaaf8b4b 100644
> --- a/tools/widl/typetree.c
> +++ b/tools/widl/typetree.c
> @@ -81,7 +81,7 @@ static const var_t *find_arg(const var_list_t *args, const char *name)
>       return NULL;
>   }
>   
> -const char *type_get_name(const type_t *type, enum name_type name_type)
> +const char *type_get_decl_name(const type_t *type, enum name_type name_type)
>   {
>       switch(name_type) {
>       case NAME_DEFAULT:
> @@ -94,13 +94,13 @@ const char *type_get_name(const type_t *type, enum name_type name_type)
>       return NULL;
>   }
>   
> -const char *type_get_qualified_name(const type_t *type, enum name_type name_type)
> +const char *type_get_name(const type_t *type, enum name_type name_type)
>   {
>       switch(name_type) {
>       case NAME_DEFAULT:
> -        return type->qualified_name;
> +        return type->qualified_name ? type->qualified_name : type->name;
>       case NAME_C:
> -        return type->c_name;
> +        return type->c_name ? type->c_name : type->name;
>       }
>   
>       assert(0);
> diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h
> index db723817266..8f5e1ebdac5 100644
> --- a/tools/widl/typetree.h
> +++ b/tools/widl/typetree.h
> @@ -77,8 +77,8 @@ type_t *type_parameterized_type_specialize_partial(type_t *type, typeref_list_t
>   type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t *params);
>   type_t *type_parameterized_type_specialize_define(type_t *type);
>   int type_is_equal(const type_t *type1, const type_t *type2);
> +const char *type_get_decl_name(const type_t *type, enum name_type name_type);
>   const char *type_get_name(const type_t *type, enum name_type name_type);
> -const char *type_get_qualified_name(const type_t *type, enum name_type name_type);
>   char *gen_name(void);
>   extern int is_attr(const attr_list_t *list, enum attr_type t);
>   
> 

Ah, this was intended as a replacement for 202329, but too late.

I think the generated C++ code was already a bit broken before though, 
as this change described it.

I'll send another version of these two patches on top of the new code.
-- 
Rémi Bernon <rbernon at codeweavers.com>



More information about the wine-devel mailing list