From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 93 +++++++++++++++++++------------------------ tools/widl/typetree.c | 12 ++++++ tools/widl/typetree.h | 1 + 3 files changed, 55 insertions(+), 51 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index ba3ad9b7bb5..52b7c5adc17 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -261,16 +261,46 @@ static void write_pointer_left(FILE *h, type_t *ref) fprintf(h, "*"); }
+static void write_record_type_definition( FILE *header, type_t *type, const char *specifier, + const char *decl_name, enum name_type name_type ) +{ + assert( type->defined ); + type->written = TRUE; + fprintf( header, "%s %s%s{\n", specifier, decl_name, *decl_name ? " " : "" ); + indentation++; + + switch (type_get_type_detect_alias( type )) + { + case TYPE_ENUM: + write_enums( header, type_enum_get_values( type ), is_global_namespace( type->namespace ) ? NULL : type->name ); + break; + case TYPE_STRUCT: + write_fields( header, type_struct_get_fields( type ), name_type ); + break; + case TYPE_ENCAPSULATED_UNION: + write_fields( header, type_encapsulated_union_get_fields( type ), name_type ); + break; + case TYPE_UNION: + write_fields( header, type_union_get_cases( type ), name_type ); + break; + default: + /* shouldn't be here */ + assert( 0 ); + break; + } + + indent( header, -1 ); + fprintf( header, "}" ); +} + void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, bool define, int write_callconv) { type_t *t = ds->type; - const char *decl_name, *name; + const char *name; struct strbuf str = {0};
if (!h) return;
- decl_name = type_get_decl_name(t, name_type); - if (ds->func_specifier & FUNCTION_SPECIFIER_INLINE) fprintf(h, "inline ");
@@ -281,57 +311,18 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b else { switch (type_get_type_detect_alias(t)) { case TYPE_ENUM: - name = type_get_name( t, name_type, true ); - if (!define) fprintf(h, "enum %s", decl_name ? decl_name : ""); - else if (!t->written) { - assert(t->defined); - if (decl_name) fprintf(h, "enum %s {\n", decl_name); - else fprintf(h, "enum {\n"); - t->written = TRUE; - indentation++; - write_enums(h, type_enum_get_values(t), is_global_namespace(t->namespace) ? NULL : t->name); - 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: - name = type_get_name( t, name_type, true ); - if (!define) fprintf(h, "struct %s", decl_name ? decl_name : ""); - else if (!t->written) { - assert(t->defined); - if (decl_name) fprintf(h, "struct %s {\n", decl_name); - else fprintf(h, "struct {\n"); - t->written = TRUE; - indentation++; - if (type_get_type(t) != TYPE_STRUCT) - write_fields(h, type_encapsulated_union_get_fields(t), name_type); - else - write_fields(h, type_struct_get_fields(t), name_type); - 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: - name = type_get_name( t, name_type, true ); - if (!define) fprintf(h, "union %s", decl_name ? decl_name : ""); - else if (!t->written) { - assert(t->defined); - if (decl_name) fprintf(h, "union %s {\n", decl_name); - else fprintf(h, "union {\n"); - t->written = TRUE; - indentation++; - write_fields(h, type_union_get_cases(t), name_type); - indent(h, -1); - fprintf(h, "}"); - } - else if (winrt_mode && name_type == NAME_DEFAULT && name) fprintf(h, "%s", name); - else fprintf(h, "union %s", name ? name : ""); - break; + { + const char *specifier = type_get_record_specifier( t ), *decl_name; + if (!(decl_name = type_get_decl_name( t, name_type ))) decl_name = ""; + if (!define) fprintf( h, "%s %s", specifier, decl_name ); + else if (!t->written) write_record_type_definition( h, t, specifier, decl_name, name_type ); + else if ((name = type_get_name( t, name_type, true )) && winrt_mode && name_type == NAME_DEFAULT) fprintf( h, "%s", name ); + else fprintf( h, "%s %s", specifier, name ? name : "" ); + break; + } case TYPE_POINTER: { write_type_left(h, type_pointer_get_ref(t), name_type, define, FALSE); diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 896c066cf8f..915917bed5d 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -96,6 +96,18 @@ const char *type_get_decl_name(const type_t *type, enum name_type name_type) return NULL; }
+const char *type_get_record_specifier( type_t *type ) +{ + switch (type_get_type_detect_alias( type )) + { + case TYPE_ENUM: return "enum"; + case TYPE_STRUCT: return "struct"; + case TYPE_ENCAPSULATED_UNION: return "struct"; + case TYPE_UNION: return "union"; + default: assert( 0 ); break; /* shouldn't be here */ + } +} + const char *type_get_name( const type_t *type, enum name_type name_type, bool record ) { const char *name; diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index 66cf35aa9df..08cc8505016 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -84,6 +84,7 @@ type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t 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); +extern const char *type_get_record_specifier( type_t *type ); extern const char *type_get_name( const type_t *type, enum name_type name_type, bool record ); char *gen_name(void);
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 132 +++++++++++++++++++++---------------------- tools/widl/header.h | 2 +- tools/widl/typegen.c | 8 +-- 3 files changed, 71 insertions(+), 71 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 52b7c5adc17..e74cba11e9a 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -293,50 +293,48 @@ static void write_record_type_definition( FILE *header, type_t *type, const char fprintf( header, "}" ); }
-void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, bool define, int write_callconv) +void write_type_left( FILE *h, const decl_spec_t *decl_spec, enum name_type name_type, bool define, bool write_callconv ) { - type_t *t = ds->type; - const char *name; - struct strbuf str = {0}; + bool is_const = !!(decl_spec->qualifier & TYPE_QUALIFIER_CONST); + type_t *type = decl_spec->type; + const char *name; + struct strbuf str = {0};
- if (!h) return; + if (!h) return;
- if (ds->func_specifier & FUNCTION_SPECIFIER_INLINE) - fprintf(h, "inline "); + if (decl_spec->func_specifier & FUNCTION_SPECIFIER_INLINE) fprintf( h, "inline " ); + if (is_const && (type_is_alias( type ) || !is_ptr( type ))) fprintf( h, "const " );
- if ((ds->qualifier & TYPE_QUALIFIER_CONST) && (type_is_alias(t) || !is_ptr(t))) - fprintf(h, "const "); + if ((name = type_get_name( type, name_type, false ))) fprintf( h, "%s", name ); + else switch (type_get_type_detect_alias( type )) + { + case TYPE_ENUM: + case TYPE_STRUCT: + case TYPE_ENCAPSULATED_UNION: + case TYPE_UNION: + { + const char *specifier = type_get_record_specifier( type ), *decl_name; + if (!(decl_name = type_get_decl_name( type, name_type ))) decl_name = ""; + if (!define) fprintf( h, "%s %s", specifier, decl_name ? decl_name : "" ); + else if (!type->written) write_record_type_definition( h, type, specifier, decl_name, name_type ); + else if ((name = type_get_name( type, name_type, true )) && winrt_mode && name_type == NAME_DEFAULT) fprintf( h, "%s", name ); + else fprintf( h, "%s %s", specifier, name ? name : "" ); + break; + }
- if ((name = type_get_name( t, name_type, false ))) fprintf(h, "%s", name); - else { - switch (type_get_type_detect_alias(t)) { - case TYPE_ENUM: - case TYPE_STRUCT: - case TYPE_ENCAPSULATED_UNION: - case TYPE_UNION: - { - const char *specifier = type_get_record_specifier( t ), *decl_name; - if (!(decl_name = type_get_decl_name( t, name_type ))) decl_name = ""; - if (!define) fprintf( h, "%s %s", specifier, decl_name ); - else if (!t->written) write_record_type_definition( h, t, specifier, decl_name, name_type ); - else if ((name = type_get_name( t, name_type, true )) && winrt_mode && name_type == NAME_DEFAULT) fprintf( h, "%s", name ); - else fprintf( h, "%s %s", specifier, name ? name : "" ); - break; - } - case TYPE_POINTER: - { - write_type_left(h, type_pointer_get_ref(t), name_type, define, FALSE); - write_pointer_left(h, type_pointer_get_ref_type(t)); - if (ds->qualifier & TYPE_QUALIFIER_CONST) fprintf(h, "const "); + case TYPE_POINTER: + write_type_left( h, type_pointer_get_ref( type ), name_type, define, false ); + write_pointer_left( h, type_pointer_get_ref_type( type ) ); + if (is_const) fprintf( h, "const " ); break; - } - case TYPE_ARRAY: - write_type_left(h, type_array_get_element(t), name_type, define, !type_array_is_decl_as_ptr(t)); - if (type_array_is_decl_as_ptr(t)) - write_pointer_left(h, type_array_get_element_type(t)); + + case TYPE_ARRAY: + write_type_left( h, type_array_get_element( type ), name_type, define, !type_array_is_decl_as_ptr( type ) ); + if (type_array_is_decl_as_ptr( type )) write_pointer_left( h, type_array_get_element_type( type ) ); break; - case TYPE_FUNCTION: - write_type_left(h, type_function_get_ret(t), name_type, define, TRUE); + + case TYPE_FUNCTION: + write_type_left( h, type_function_get_ret( type ), name_type, define, true );
/* A pointer to a function has to write the calling convention inside * the parentheses. There's no way to handle that here, so we have to @@ -344,39 +342,41 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, b * convention or not. */ if (write_callconv) { - const char *callconv = get_attrp(t->attrs, ATTR_CALLCONV); + const char *callconv = get_attrp( type->attrs, ATTR_CALLCONV ); if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE"; - if (callconv) fprintf(h, " %s ", callconv); + if (callconv) fprintf( h, " %s ", callconv ); } break; - case TYPE_BASIC: - append_basic_type( &str, t ); - fwrite( str.buf, 1, str.pos, h ); - break; - case TYPE_BITFIELD: - t = type_bitfield_get_field( t ); - if (!type_is_alias( t )) append_basic_type( &str, t ); - else strappend( &str, "%s", type_get_name( t, name_type, false ) ); - fwrite( str.buf, 1, str.pos, h ); - break; - case TYPE_INTERFACE: - case TYPE_MODULE: - case TYPE_COCLASS: - case TYPE_RUNTIMECLASS: - case TYPE_DELEGATE: - case TYPE_VOID: - case TYPE_ALIAS: - case TYPE_PARAMETERIZED_TYPE: - case TYPE_PARAMETER: + + case TYPE_BASIC: + append_basic_type( &str, type ); + fwrite( str.buf, 1, str.pos, h ); + break; + case TYPE_BITFIELD: + type = type_bitfield_get_field( type ); + if (!type_is_alias( type )) append_basic_type( &str, type ); + else strappend( &str, "%s", type_get_name( type, name_type, false ) ); + fwrite( str.buf, 1, str.pos, h ); + break; + + case TYPE_INTERFACE: + case TYPE_MODULE: + case TYPE_COCLASS: + case TYPE_RUNTIMECLASS: + case TYPE_DELEGATE: + case TYPE_VOID: + case TYPE_ALIAS: + case TYPE_PARAMETERIZED_TYPE: + case TYPE_PARAMETER: /* handled elsewhere */ - assert(0); + assert( 0 ); break; - case TYPE_APICONTRACT: + + case TYPE_APICONTRACT: /* shouldn't be here */ - assert(0); + assert( 0 ); break; } - } }
void write_type_right(FILE *h, type_t *t, int is_field) @@ -454,7 +454,7 @@ static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, bool defi
if (!h) return;
- if (t) write_type_left(h, ds, name_type, define, TRUE); + if (t) write_type_left( h, ds, name_type, define, true );
if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
@@ -482,14 +482,14 @@ static void write_type_definition(FILE *f, type_t *t, bool define) write_namespace_start(f, t->namespace); } indent(f, 0); - write_type_left(f, &ds, NAME_DEFAULT, define, TRUE); + write_type_left( f, &ds, NAME_DEFAULT, define, true ); fprintf(f, ";\n"); if(in_namespace) { t->written = false; write_namespace_end(f, t->namespace); fprintf(f, "extern "C" {\n"); fprintf(f, "#else\n"); - write_type_left(f, &ds, NAME_C, define, TRUE); + write_type_left( f, &ds, NAME_C, define, true ); fprintf(f, ";\n"); if (winrt_mode) write_widl_using_macros(f, t); fprintf(f, "#endif\n\n"); @@ -506,7 +506,7 @@ void write_type_decl(FILE *f, const decl_spec_t *t, const char *name)
void write_type_decl_left(FILE *f, const decl_spec_t *ds) { - write_type_left(f, ds, NAME_DEFAULT, false, TRUE); + write_type_left( f, ds, NAME_DEFAULT, false, true ); }
static int user_type_registered(const char *name) diff --git a/tools/widl/header.h b/tools/widl/header.h index 45066898a66..77f810ca349 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -24,7 +24,7 @@ #include "typetree.h"
extern const char* get_name(const var_t *v); -extern void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, bool define, int write_callconv); +extern void write_type_left( FILE *h, const decl_spec_t *ds, enum name_type name_type, bool define, bool write_callconv ); extern void write_type_right(FILE *h, type_t *t, int is_field); extern void write_type_decl(FILE *f, const decl_spec_t *t, const char *name); extern void write_type_decl_left(FILE *f, const decl_spec_t *ds); diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 6d7ccd30814..4f4a4c801f5 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -5064,7 +5064,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun { print_file(file, 2, "%s", ""); init_param_struct_declspec( &declspec, &arg->declspec ); - write_type_left( file, &declspec, NAME_DEFAULT, false, TRUE ); + write_type_left( file, &declspec, NAME_DEFAULT, false, true ); if (needs_space_after( arg->declspec.type )) fputc( ' ', file ); if (is_array( arg->declspec.type ) && !type_array_is_decl_as_ptr( arg->declspec.type )) fputc( '*', file );
@@ -5081,7 +5081,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun { print_file(file, 2, "%s", ""); init_param_struct_declspec( &declspec, &retval->declspec ); - write_type_left( file, &declspec, NAME_DEFAULT, false, TRUE ); + write_type_left( file, &declspec, NAME_DEFAULT, false, true ); if (needs_space_after( retval->declspec.type )) fputc( ' ', file ); if (!is_array( retval->declspec.type ) && !is_ptr( retval->declspec.type ) && type_memsize( retval->declspec.type ) != pointer_size) @@ -5132,9 +5132,9 @@ int write_expr_eval_routines(FILE *file, const char *iface) { decl_spec_t ds = {.type = (type_t *)eval->cont_type}; print_file(file, 1, "%s", ""); - write_type_left(file, &ds, NAME_DEFAULT, false, TRUE); + write_type_left( file, &ds, NAME_DEFAULT, false, true ); fprintf(file, " *%s = (", var_name); - write_type_left(file, &ds, NAME_DEFAULT, false, TRUE); + write_type_left( file, &ds, NAME_DEFAULT, false, true ); fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff); } print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 175 +++++++++++++++++++++++++++++++++---------- tools/widl/header.h | 2 +- tools/widl/typegen.c | 8 +- 3 files changed, 139 insertions(+), 46 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index e74cba11e9a..69889c22b67 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -40,8 +40,6 @@ user_type_list_t user_type_list = LIST_INIT(user_type_list); context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
-static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, bool define, const char *name, enum name_type name_type); - static void write_apicontract( FILE *header, type_t *type ); static void write_apicontract_guard_start(FILE *header, const expr_t *expr); static void write_apicontract_guard_end(FILE *header, const expr_t *expr); @@ -140,6 +138,27 @@ const char *get_name(const var_t *v) return v->name; }
+static void write_type_definition_left( FILE *h, const decl_spec_t *ds, enum name_type name_type, bool write_callconv ); +static void write_type_definition( FILE *h, const decl_spec_t *ds, bool is_field, const char *name, enum name_type name_type ) +{ + type_t *t = ds->type; + + if (!h) return; + if (t) write_type_definition_left( h, ds, name_type, true ); + if (name) fprintf( h, "%s%s", !t || needs_space_after( t ) ? " " : "", name ); + if (t) write_type_right( h, t, is_field ); +} + +static void write_type_v( FILE *h, const decl_spec_t *ds, bool is_field, const char *name, enum name_type name_type ) +{ + type_t *t = ds->type; + + if (!h) return; + if (t) write_type_left( h, ds, name_type, true ); + if (name) fprintf( h, "%s%s", !t || needs_space_after( t ) ? " " : "", name ); + if (t) write_type_right( h, t, is_field ); +} + static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type) { unsigned nameless_struct_cnt = 0, nameless_struct_i = 0, nameless_union_cnt = 0, nameless_union_i = 0; @@ -200,7 +219,8 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type) default: ; } - write_type_v(h, &v->declspec, TRUE, v->is_defined, name, name_type); + if (v->is_defined) write_type_definition( h, &v->declspec, true, name, name_type ); + else write_type_v( h, &v->declspec, true, name, name_type ); fprintf(h, ";\n"); if (contract) write_apicontract_guard_end(h, contract); } @@ -261,11 +281,14 @@ static void write_pointer_left(FILE *h, type_t *ref) fprintf(h, "*"); }
-static void write_record_type_definition( FILE *header, type_t *type, const char *specifier, - const char *decl_name, enum name_type name_type ) +static void write_record_type_definition( FILE *header, type_t *type, const char *specifier, enum name_type name_type ) { + const char *decl_name; + assert( type->defined ); type->written = TRUE; + + if (!(decl_name = type_get_decl_name( type, name_type ))) decl_name = ""; fprintf( header, "%s %s%s{\n", specifier, decl_name, *decl_name ? " " : "" ); indentation++;
@@ -293,7 +316,7 @@ static void write_record_type_definition( FILE *header, type_t *type, const char fprintf( header, "}" ); }
-void write_type_left( FILE *h, const decl_spec_t *decl_spec, enum name_type name_type, bool define, bool write_callconv ) +static void write_type_definition_left( FILE *h, const decl_spec_t *decl_spec, enum name_type name_type, bool write_callconv ) { bool is_const = !!(decl_spec->qualifier & TYPE_QUALIFIER_CONST); type_t *type = decl_spec->type; @@ -313,28 +336,108 @@ void write_type_left( FILE *h, const decl_spec_t *decl_spec, enum name_type name case TYPE_ENCAPSULATED_UNION: case TYPE_UNION: { - const char *specifier = type_get_record_specifier( type ), *decl_name; - if (!(decl_name = type_get_decl_name( type, name_type ))) decl_name = ""; - if (!define) fprintf( h, "%s %s", specifier, decl_name ? decl_name : "" ); - else if (!type->written) write_record_type_definition( h, type, specifier, decl_name, name_type ); + const char *specifier = type_get_record_specifier( type ); + if (!type->written) write_record_type_definition( h, type, specifier, name_type ); else if ((name = type_get_name( type, name_type, true )) && winrt_mode && name_type == NAME_DEFAULT) fprintf( h, "%s", name ); else fprintf( h, "%s %s", specifier, name ? name : "" ); break; }
case TYPE_POINTER: - write_type_left( h, type_pointer_get_ref( type ), name_type, define, false ); + write_type_definition_left( h, type_pointer_get_ref( type ), name_type, false ); write_pointer_left( h, type_pointer_get_ref_type( type ) ); if (is_const) fprintf( h, "const " ); break;
case TYPE_ARRAY: - write_type_left( h, type_array_get_element( type ), name_type, define, !type_array_is_decl_as_ptr( type ) ); + write_type_definition_left( h, type_array_get_element( type ), name_type, !type_array_is_decl_as_ptr( type ) ); if (type_array_is_decl_as_ptr( type )) write_pointer_left( h, type_array_get_element_type( type ) ); break;
case TYPE_FUNCTION: - write_type_left( h, type_function_get_ret( type ), name_type, define, true ); + write_type_definition_left( h, type_function_get_ret( type ), name_type, true ); + + /* A pointer to a function has to write the calling convention inside + * the parentheses. There's no way to handle that here, so we have to + * use an extra parameter to tell us whether to write the calling + * convention or not. */ + if (write_callconv) + { + const char *callconv = get_attrp( type->attrs, ATTR_CALLCONV ); + if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE"; + if (callconv) fprintf( h, " %s ", callconv ); + } + break; + + case TYPE_BASIC: + append_basic_type( &str, type ); + fwrite( str.buf, 1, str.pos, h ); + break; + case TYPE_BITFIELD: + type = type_bitfield_get_field( type ); + if (!type_is_alias( type )) append_basic_type( &str, type ); + else strappend( &str, "%s", type_get_name( type, name_type, false ) ); + fwrite( str.buf, 1, str.pos, h ); + break; + + case TYPE_INTERFACE: + case TYPE_MODULE: + case TYPE_COCLASS: + case TYPE_RUNTIMECLASS: + case TYPE_DELEGATE: + case TYPE_VOID: + case TYPE_ALIAS: + case TYPE_PARAMETERIZED_TYPE: + case TYPE_PARAMETER: + /* handled elsewhere */ + assert( 0 ); + break; + case TYPE_APICONTRACT: + /* shouldn't be here */ + assert( 0 ); + break; + } +} + +void write_type_left( FILE *h, const decl_spec_t *decl_spec, enum name_type name_type, bool write_callconv ) +{ + bool is_const = !!(decl_spec->qualifier & TYPE_QUALIFIER_CONST); + type_t *type = decl_spec->type; + struct strbuf str = {0}; + const char *name; + + if (!h) return; + + if (decl_spec->func_specifier & FUNCTION_SPECIFIER_INLINE) fprintf( h, "inline " ); + if (is_const && (type_is_alias( type ) || !is_ptr( type ))) fprintf( h, "const " ); + + if ((name = type_get_name( type, name_type, false ))) fprintf( h, "%s", name ); + else switch (type_get_type_detect_alias( type )) + { + case TYPE_ENUM: + case TYPE_STRUCT: + case TYPE_ENCAPSULATED_UNION: + case TYPE_UNION: + { + const char *specifier = type_get_record_specifier( type ), *decl_name; + if (!(decl_name = type_get_decl_name( type, name_type ))) decl_name = ""; + fprintf( h, "%s %s", specifier, decl_name ); + break; + } + + case TYPE_POINTER: + write_type_left( h, type_pointer_get_ref( type ), name_type, false ); + write_pointer_left( h, type_pointer_get_ref_type( type ) ); + if (is_const) fprintf( h, "const " ); + break; + + case TYPE_ARRAY: + write_type_left( h, type_array_get_element( type ), name_type, !type_array_is_decl_as_ptr( type ) ); + if (type_array_is_decl_as_ptr( type )) write_pointer_left( h, type_array_get_element_type( type ) ); + break; + + case TYPE_FUNCTION: + write_type_left( h, type_function_get_ret( type ), name_type, true );
/* A pointer to a function has to write the calling convention inside * the parentheses. There's no way to handle that here, so we have to @@ -448,21 +551,7 @@ void write_type_right(FILE *h, type_t *t, int is_field) } }
-static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, bool define, const char *name, enum name_type name_type) -{ - type_t *t = ds->type; - - if (!h) return; - - if (t) write_type_left( h, ds, name_type, define, true ); - - if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name ); - - if (t) - write_type_right(h, t, is_field); -} - -static void write_type_definition(FILE *f, type_t *t, bool define) +static void write_type( FILE *f, type_t *t, bool define ) { int in_namespace = t->namespace && !is_global_namespace(t->namespace); decl_spec_t ds = {.type = t}; @@ -482,14 +571,16 @@ static void write_type_definition(FILE *f, type_t *t, bool define) write_namespace_start(f, t->namespace); } indent(f, 0); - write_type_left( f, &ds, NAME_DEFAULT, define, true ); + if (define) write_type_definition_left( f, &ds, NAME_DEFAULT, true ); + else write_type_left( f, &ds, NAME_DEFAULT, true ); fprintf(f, ";\n"); if(in_namespace) { t->written = false; write_namespace_end(f, t->namespace); fprintf(f, "extern "C" {\n"); fprintf(f, "#else\n"); - write_type_left( f, &ds, NAME_C, define, true ); + if (define) write_type_definition_left( f, &ds, NAME_C, true ); + else write_type_left( f, &ds, NAME_C, true ); fprintf(f, ";\n"); if (winrt_mode) write_widl_using_macros(f, t); fprintf(f, "#endif\n\n"); @@ -501,12 +592,12 @@ static void write_type_definition(FILE *f, type_t *t, bool define)
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name) { - write_type_v(f, t, FALSE, false, name, NAME_DEFAULT); + write_type_v( f, t, false, name, NAME_DEFAULT ); }
void write_type_decl_left(FILE *f, const decl_spec_t *ds) { - write_type_left( f, ds, NAME_DEFAULT, false, true ); + write_type_left( f, ds, NAME_DEFAULT, true ); }
static int user_type_registered(const char *name) @@ -730,13 +821,13 @@ static void write_generic_handle_routines(FILE *header) static void write_typedef(FILE *header, type_t *type, bool define) { type_t *t = type_alias_get_aliasee_type(type), *root = type_pointer_get_root_type(t); - if (winrt_mode && !define && type_get_type( t ) == TYPE_ENUM) - write_type_definition( header, t, TRUE ); + if (winrt_mode && !define && type_get_type( t ) == TYPE_ENUM) write_type( header, t, true ); if (winrt_mode && root->namespace && !is_global_namespace(root->namespace)) { fprintf(header, "#ifndef __cplusplus\n"); fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, define, type->c_name, NAME_C); + if (define) write_type_definition( header, type_alias_get_aliasee( type ), false, type->c_name, NAME_C ); + else write_type_v( header, type_alias_get_aliasee( type ), false, type->c_name, NAME_C ); fprintf(header, ";\n"); if (type_get_type_detect_alias(t) != TYPE_ENUM) { @@ -744,7 +835,7 @@ static void write_typedef(FILE *header, type_t *type, bool define) if (t->namespace && !is_global_namespace(t->namespace)) write_namespace_start(header, t->namespace); indent(header, 0); fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, false, type->name, NAME_DEFAULT); + write_type_v( header, type_alias_get_aliasee( type ), false, type->name, NAME_DEFAULT ); fprintf(header, ";\n"); if (t->namespace && !is_global_namespace(t->namespace)) write_namespace_end(header, t->namespace); } @@ -753,7 +844,8 @@ static void write_typedef(FILE *header, type_t *type, bool define) else { fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, define, type->name, NAME_DEFAULT); + if (define) write_type_definition( header, type_alias_get_aliasee( type ), false, type->name, NAME_DEFAULT ); + else write_type_v( header, type_alias_get_aliasee( type ), false, type->name, NAME_DEFAULT ); fprintf(header, ";\n"); } } @@ -798,7 +890,8 @@ static void write_declaration(FILE *header, const var_t *v) fprintf(header, "extern "); break; } - write_type_v(header, &v->declspec, FALSE, v->is_defined, v->name, NAME_DEFAULT); + if (v->is_defined) write_type_definition( header, &v->declspec, false, v->name, NAME_DEFAULT ); + else write_type_v( header, &v->declspec, false, v->name, NAME_DEFAULT ); fprintf(header, ";\n\n"); } } @@ -1042,7 +1135,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i /* In theory we should be writing the definition using write_type_v(..., arg->define), * but that causes redefinition in e.g. proxy files. In fact MIDL disallows * defining UDTs inside of an argument list. */ - write_type_v(h, &arg->declspec, FALSE, false, arg->name, name_type); + write_type_v( h, &arg->declspec, false, arg->name, name_type ); if (method == 2) { const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE); if (expr) { @@ -1943,8 +2036,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); - else if (type_get_type(stmt->u.type) != TYPE_PARAMETERIZED_TYPE) - write_type_definition(header, stmt->u.type, stmt->is_defined); + else if (type_get_type( stmt->u.type ) != TYPE_PARAMETERIZED_TYPE) + write_type( header, stmt->u.type, stmt->is_defined ); else { is_object_interface++; diff --git a/tools/widl/header.h b/tools/widl/header.h index 77f810ca349..59c12007019 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -24,7 +24,7 @@ #include "typetree.h"
extern const char* get_name(const var_t *v); -extern void write_type_left( FILE *h, const decl_spec_t *ds, enum name_type name_type, bool define, bool write_callconv ); +extern void write_type_left( FILE *h, const decl_spec_t *ds, enum name_type name_type, bool write_callconv ); extern void write_type_right(FILE *h, type_t *t, int is_field); extern void write_type_decl(FILE *f, const decl_spec_t *t, const char *name); extern void write_type_decl_left(FILE *f, const decl_spec_t *ds); diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 4f4a4c801f5..cb8e030a206 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -5064,7 +5064,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun { print_file(file, 2, "%s", ""); init_param_struct_declspec( &declspec, &arg->declspec ); - write_type_left( file, &declspec, NAME_DEFAULT, false, true ); + write_type_left( file, &declspec, NAME_DEFAULT, true ); if (needs_space_after( arg->declspec.type )) fputc( ' ', file ); if (is_array( arg->declspec.type ) && !type_array_is_decl_as_ptr( arg->declspec.type )) fputc( '*', file );
@@ -5081,7 +5081,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun { print_file(file, 2, "%s", ""); init_param_struct_declspec( &declspec, &retval->declspec ); - write_type_left( file, &declspec, NAME_DEFAULT, false, true ); + write_type_left( file, &declspec, NAME_DEFAULT, true ); if (needs_space_after( retval->declspec.type )) fputc( ' ', file ); if (!is_array( retval->declspec.type ) && !is_ptr( retval->declspec.type ) && type_memsize( retval->declspec.type ) != pointer_size) @@ -5132,9 +5132,9 @@ int write_expr_eval_routines(FILE *file, const char *iface) { decl_spec_t ds = {.type = (type_t *)eval->cont_type}; print_file(file, 1, "%s", ""); - write_type_left( file, &ds, NAME_DEFAULT, false, true ); + write_type_left( file, &ds, NAME_DEFAULT, true ); fprintf(file, " *%s = (", var_name); - write_type_left( file, &ds, NAME_DEFAULT, false, true ); + write_type_left( file, &ds, NAME_DEFAULT, true ); fprintf(file, " *)(pStubMsg->StackTop - %u);\n", eval->baseoff); } print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
From: Rémi Bernon rbernon@codeweavers.com
--- tools/widl/header.c | 110 +++-------------------------------------- tools/widl/header.h | 1 - tools/widl/typetree.c | 112 ++++++++++++++++++++++++++++++++++++++++++ tools/widl/typetree.h | 6 +++ 4 files changed, 124 insertions(+), 105 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 69889c22b67..a14c9e16946 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -251,34 +251,11 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name) } }
-int needs_space_after(type_t *t) -{ - return (type_is_alias(t) || - (!is_ptr(t) && (!is_array(t) || !type_array_is_decl_as_ptr(t) || t->name))); -} - -static int decl_needs_parens(const type_t *t) -{ - if (type_is_alias(t)) - return FALSE; - if (is_array(t) && !type_array_is_decl_as_ptr(t)) - return TRUE; - return is_func(t); -} - static void write_pointer_left(FILE *h, type_t *ref) { - if (needs_space_after(ref)) - fprintf(h, " "); - if (decl_needs_parens(ref)) - fprintf(h, "("); - if (type_get_type_detect_alias(ref) == TYPE_FUNCTION) - { - const char *callconv = get_attrp(ref->attrs, ATTR_CALLCONV); - if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE"; - if (callconv) fprintf(h, "%s ", callconv); - } - fprintf(h, "*"); + struct strbuf str = {0}; + append_pointer_left( &str, ref, is_object_interface ? "STDMETHODCALLTYPE" : "" ); + fwrite( str.buf, 1, str.pos, h ); }
static void write_record_type_definition( FILE *header, type_t *type, const char *specifier, enum name_type name_type ) @@ -399,87 +376,12 @@ static void write_type_definition_left( FILE *h, const decl_spec_t *decl_spec, e } }
-void write_type_left( FILE *h, const decl_spec_t *decl_spec, enum name_type name_type, bool write_callconv ) +void write_type_left( FILE *h, const decl_spec_t *ds, enum name_type name_type, bool write_callconv ) { - bool is_const = !!(decl_spec->qualifier & TYPE_QUALIFIER_CONST); - type_t *type = decl_spec->type; struct strbuf str = {0}; - const char *name; - if (!h) return; - - if (decl_spec->func_specifier & FUNCTION_SPECIFIER_INLINE) fprintf( h, "inline " ); - if (is_const && (type_is_alias( type ) || !is_ptr( type ))) fprintf( h, "const " ); - - if ((name = type_get_name( type, name_type, false ))) fprintf( h, "%s", name ); - else switch (type_get_type_detect_alias( type )) - { - case TYPE_ENUM: - case TYPE_STRUCT: - case TYPE_ENCAPSULATED_UNION: - case TYPE_UNION: - { - const char *specifier = type_get_record_specifier( type ), *decl_name; - if (!(decl_name = type_get_decl_name( type, name_type ))) decl_name = ""; - fprintf( h, "%s %s", specifier, decl_name ); - break; - } - - case TYPE_POINTER: - write_type_left( h, type_pointer_get_ref( type ), name_type, false ); - write_pointer_left( h, type_pointer_get_ref_type( type ) ); - if (is_const) fprintf( h, "const " ); - break; - - case TYPE_ARRAY: - write_type_left( h, type_array_get_element( type ), name_type, !type_array_is_decl_as_ptr( type ) ); - if (type_array_is_decl_as_ptr( type )) write_pointer_left( h, type_array_get_element_type( type ) ); - break; - - case TYPE_FUNCTION: - write_type_left( h, type_function_get_ret( type ), name_type, true ); - - /* A pointer to a function has to write the calling convention inside - * the parentheses. There's no way to handle that here, so we have to - * use an extra parameter to tell us whether to write the calling - * convention or not. */ - if (write_callconv) - { - const char *callconv = get_attrp( type->attrs, ATTR_CALLCONV ); - if (!callconv && is_object_interface) callconv = "STDMETHODCALLTYPE"; - if (callconv) fprintf( h, " %s ", callconv ); - } - break; - - case TYPE_BASIC: - append_basic_type( &str, type ); - fwrite( str.buf, 1, str.pos, h ); - break; - case TYPE_BITFIELD: - type = type_bitfield_get_field( type ); - if (!type_is_alias( type )) append_basic_type( &str, type ); - else strappend( &str, "%s", type_get_name( type, name_type, false ) ); - fwrite( str.buf, 1, str.pos, h ); - break; - - case TYPE_INTERFACE: - case TYPE_MODULE: - case TYPE_COCLASS: - case TYPE_RUNTIMECLASS: - case TYPE_DELEGATE: - case TYPE_VOID: - case TYPE_ALIAS: - case TYPE_PARAMETERIZED_TYPE: - case TYPE_PARAMETER: - /* handled elsewhere */ - assert( 0 ); - break; - - case TYPE_APICONTRACT: - /* shouldn't be here */ - assert( 0 ); - break; - } + append_type_left( &str, ds, name_type, write_callconv ? is_object_interface ? "STDMETHODCALLTYPE" : "" : NULL ); + fwrite( str.buf, 1, str.pos, h ); }
void write_type_right(FILE *h, type_t *t, int is_field) diff --git a/tools/widl/header.h b/tools/widl/header.h index 59c12007019..e995815ee8b 100644 --- a/tools/widl/header.h +++ b/tools/widl/header.h @@ -30,7 +30,6 @@ extern void write_type_decl(FILE *f, const decl_spec_t *t, const char *name); extern void write_type_decl_left(FILE *f, const decl_spec_t *ds); extern unsigned int get_context_handle_offset( const type_t *type ); extern unsigned int get_generic_handle_offset( const type_t *type ); -extern int needs_space_after(type_t *t); extern int is_object(const type_t *iface); extern int is_local(const attr_list_t *list); extern int count_methods(const type_t *iface); diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 915917bed5d..20081980422 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -190,6 +190,118 @@ void append_basic_type( struct strbuf *str, const type_t *type ) } }
+bool needs_space_after( const type_t *type ) +{ + if (type_is_alias( type )) return true; + if (type_get_type( type ) == TYPE_POINTER) return false; + if (type_get_type( type ) != TYPE_ARRAY) return true; + if (!type_array_is_decl_as_ptr( type )) return true; + if (type->name) return true; + return false; +} + +bool decl_needs_parens( const type_t *type ) +{ + if (type_is_alias( type )) return false; + if (is_array( type ) && !type_array_is_decl_as_ptr( type )) return true; + if (type_get_type( type ) == TYPE_FUNCTION) return true; + return false; +} + +void append_pointer_left( struct strbuf *str, const type_t *type, const char *callconv ) +{ + if (needs_space_after( type )) strappend( str, " " ); + if (decl_needs_parens( type )) strappend( str, "(" ); + if (callconv && type_get_type_detect_alias( type ) == TYPE_FUNCTION) + { + const char *explicit_callconv = get_attrp( type->attrs, ATTR_CALLCONV ); + if (explicit_callconv) callconv = explicit_callconv; + if (*callconv) strappend( str, "%s ", callconv ); + } + strappend( str, "*" ); +} + +void append_type_left( struct strbuf *str, const decl_spec_t *decl_spec, enum name_type name_type, + const char *callconv ) +{ + bool is_const = !!(decl_spec->qualifier & TYPE_QUALIFIER_CONST); + type_t *type = decl_spec->type; + const char *name; + + if (decl_spec->func_specifier & FUNCTION_SPECIFIER_INLINE) strappend( str, "inline " ); + if (is_const && (type_is_alias( type ) || !is_ptr( type ))) strappend( str, "const " ); + + if ((name = type_get_name( type, name_type, false ))) return strappend( str, "%s", name ); + + switch (type_get_type_detect_alias( type )) + { + case TYPE_ENUM: + case TYPE_STRUCT: + case TYPE_ENCAPSULATED_UNION: + case TYPE_UNION: + { + const char *specifier = type_get_record_specifier( type ), *decl_name; + if (!(decl_name = type_get_decl_name( type, name_type ))) decl_name = ""; + return strappend( str, "%s %s", specifier, decl_name ); + } + + case TYPE_POINTER: + append_type_left( str, type_pointer_get_ref( type ), name_type, NULL ); + append_pointer_left( str, type_pointer_get_ref_type( type ), callconv ); + if (is_const) strappend( str, "const " ); + return; + + case TYPE_ARRAY: + { + bool as_pointer = type_array_is_decl_as_ptr( type ); + append_type_left( str, type_array_get_element( type ), name_type, as_pointer ? NULL : callconv ); + if (as_pointer) append_pointer_left( str, type_array_get_element_type( type ), callconv ); + return; + } + + case TYPE_FUNCTION: + append_type_left( str, type_function_get_ret( type ), name_type, callconv ); + + /* A pointer to a function has to write the calling convention inside + * the parentheses. There's no way to handle that here, so we have to + * use an extra parameter to tell us whether to write the calling + * convention or not. */ + if (callconv) + { + const char *explicit_callconv = get_attrp( type->attrs, ATTR_CALLCONV ); + if (explicit_callconv) callconv = explicit_callconv; + if (*callconv) strappend( str, " %s ", callconv ); + } + return; + + case TYPE_BASIC: + return append_basic_type( str, type ); + + case TYPE_BITFIELD: + type = type_bitfield_get_field( type ); + if (!type_is_alias( type )) return append_basic_type( str, type ); + return strappend( str, "%s", type_get_name( type, name_type, false ) ); + + case TYPE_INTERFACE: + case TYPE_MODULE: + case TYPE_COCLASS: + case TYPE_RUNTIMECLASS: + case TYPE_DELEGATE: + case TYPE_VOID: + case TYPE_ALIAS: + case TYPE_PARAMETERIZED_TYPE: + case TYPE_PARAMETER: + /* handled elsewhere */ + assert( 0 ); + break; + + case TYPE_APICONTRACT: + /* shouldn't be here */ + assert( 0 ); + break; + } +} + static void append_namespace( struct strbuf *str, const struct namespace *namespace, const char *separator, const char *abi_prefix ) { diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index 08cc8505016..9c2844aad4a 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -88,7 +88,13 @@ extern const char *type_get_record_specifier( type_t *type ); extern const char *type_get_name( const type_t *type, enum name_type name_type, bool record ); char *gen_name(void);
+extern bool needs_space_after( const type_t *type ); +extern bool decl_needs_parens( const type_t *type ); + extern void append_basic_type( struct strbuf *str, const type_t *type ); +extern void append_pointer_left( struct strbuf *str, const type_t *type, const char *callconv ); +extern void append_type_left( struct strbuf *str, const decl_spec_t *decl_spec, enum name_type name_type, + const char *callconv );
extern char *format_namespace( const struct namespace *namespace, const char *prefix, const char *separator, const char *suffix, const char *abi_prefix );
This merge request was approved by Huw Davies.