From: Elizabeth Figura zfigura@codeweavers.com
yyloc is an internal variable; we want to assign to yylloc here.
This fixes error reporting.
Fixes: 3b12583db0cf68b356f20d7bbd091651af246eff --- tools/widl/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 9b6a4c36732..e5e28fd7b24 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -515,7 +515,7 @@ cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; }
import_start: tIMPORT aSTRING ';' { $$ = $2; push_import( $2, &yylloc ); } ; -import: import_start imp_statements aEOF { yyloc = pop_import(); } +import: import_start imp_statements aEOF { yylloc = pop_import(); } ;
importlib: tIMPORTLIB '(' aSTRING ')'
From: Elizabeth Figura zfigura@codeweavers.com
E.g. in cases like
typedef int apple; struct apple { ... };
allow subsequently using "struct apple" in future expressions. Note that this already worked for UDT definitions (so the above example by itself was legal in widl), but any attempt to use the defined type would result in a syntax error. --- tools/widl/parser.y | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index e5e28fd7b24..1fe9e1139c8 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -500,11 +500,11 @@ warnings:
typedecl: enumdef - | tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); } + | tENUM typename { $$ = type_new_enum($2, current_namespace, FALSE, NULL); } | structdef - | tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, current_namespace, FALSE, NULL); } + | tSTRUCT typename { $$ = type_new_struct($2, current_namespace, FALSE, NULL); } | uniondef - | tUNION aIDENTIFIER { $$ = type_new_nonencapsulated_union($2, current_namespace, FALSE, NULL); } + | tUNION typename { $$ = type_new_nonencapsulated_union($2, current_namespace, FALSE, NULL); } | attributes enumdef { $$ = $2; $$->attrs = check_enum_attrs($1); } | attributes structdef { $$ = $2; $$->attrs = check_struct_attrs($1); } | attributes uniondef { $$ = $2; $$->attrs = check_union_attrs($1); } @@ -1341,11 +1341,11 @@ unqualified_type: tVOID { $$ = type_new_void(); } | base_type { $$ = $1; } | enumdef { $$ = $1; } - | tENUM aIDENTIFIER { $$ = type_new_enum($2, current_namespace, FALSE, NULL); } + | tENUM typename { $$ = type_new_enum($2, current_namespace, FALSE, NULL); } | structdef { $$ = $1; } - | tSTRUCT aIDENTIFIER { $$ = type_new_struct($2, current_namespace, FALSE, NULL); } + | tSTRUCT typename { $$ = type_new_struct($2, current_namespace, FALSE, NULL); } | uniondef { $$ = $1; } - | tUNION aIDENTIFIER { $$ = type_new_nonencapsulated_union($2, current_namespace, FALSE, NULL); } + | tUNION typename { $$ = type_new_nonencapsulated_union($2, current_namespace, FALSE, NULL); } | tSAFEARRAY '(' type ')' { $$ = make_safearray($3); } | aKNOWNTYPE { $$ = find_type_or_error(current_namespace, $1); } ;
From: Elizabeth Figura zfigura@codeweavers.com
This makes the logic around it a bit simpler, and I find it easier to understand as well. --- tools/widl/header.c | 58 +++++++++++++++++++++--------------------- tools/widl/header.h | 2 +- tools/widl/parser.y | 16 ++++++------ tools/widl/typegen.c | 8 +++--- tools/widl/widltypes.h | 8 ++++-- 5 files changed, 48 insertions(+), 44 deletions(-)
diff --git a/tools/widl/header.c b/tools/widl/header.c index 624d38094f9..f5e21ccdb29 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -40,7 +40,7 @@ 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, int declonly, const char *name, enum name_type name_type); +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_guard_start(FILE *header, const expr_t *expr); static void write_apicontract_guard_end(FILE *header, const expr_t *expr); @@ -218,7 +218,7 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type) default: ; } - write_type_v(h, &v->declspec, TRUE, v->declonly, name, name_type); + write_type_v(h, &v->declspec, TRUE, v->define, name, name_type); fprintf(h, ";\n"); if (contract) write_apicontract_guard_end(h, contract); } @@ -279,7 +279,7 @@ static void write_pointer_left(FILE *h, type_t *ref) fprintf(h, "*"); }
-void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, int declonly, int write_callconv) +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; @@ -300,7 +300,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i else { switch (type_get_type_detect_alias(t)) { case TYPE_ENUM: - if (declonly) fprintf(h, "enum %s", decl_name ? decl_name : ""); + 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); @@ -316,7 +316,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i break; case TYPE_STRUCT: case TYPE_ENCAPSULATED_UNION: - if (declonly) fprintf(h, "struct %s", decl_name ? decl_name : ""); + 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); @@ -334,7 +334,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i else fprintf(h, "struct %s", name ? name : ""); break; case TYPE_UNION: - if (declonly) fprintf(h, "union %s", decl_name ? decl_name : ""); + 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); @@ -350,7 +350,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i break; case TYPE_POINTER: { - write_type_left(h, type_pointer_get_ref(t), name_type, declonly, FALSE); + 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 "); break; @@ -360,14 +360,14 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i fprintf(h, "%s", t->name); else { - write_type_left(h, type_array_get_element(t), name_type, declonly, !type_array_is_decl_as_ptr(t)); + 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)); } break; case TYPE_FUNCTION: { - write_type_left(h, type_function_get_ret(t), name_type, declonly, TRUE); + write_type_left(h, type_function_get_ret(t), 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 @@ -446,7 +446,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i case TYPE_BITFIELD: { const decl_spec_t ds = {.type = type_bitfield_get_field(t)}; - write_type_left(h, &ds, name_type, declonly, TRUE); + write_type_left(h, &ds, name_type, define, TRUE); break; } case TYPE_ALIAS: @@ -454,7 +454,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i const decl_spec_t *ds = type_alias_get_aliasee(t); int in_namespace = ds && ds->type && ds->type->namespace && !is_global_namespace(ds->type->namespace); if (!in_namespace) fprintf(h, "%s", t->name); - else write_type_left(h, ds, name_type, declonly, write_callconv); + else write_type_left(h, ds, name_type, define, write_callconv); break; } case TYPE_PARAMETERIZED_TYPE: @@ -546,13 +546,13 @@ 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, int declonly, const char *name, enum name_type name_type) +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, declonly, TRUE); + if (t) write_type_left(h, ds, name_type, define, TRUE);
if (name) fprintf(h, "%s%s", !t || needs_space_after(t) ? " " : "", name );
@@ -560,7 +560,7 @@ static void write_type_v(FILE *h, const decl_spec_t *ds, int is_field, int declo write_type_right(h, t, is_field); }
-static void write_type_definition(FILE *f, type_t *t, int declonly) +static void write_type_definition(FILE *f, type_t *t, bool define) { int in_namespace = t->namespace && !is_global_namespace(t->namespace); int save_written = t->written; @@ -574,14 +574,14 @@ static void write_type_definition(FILE *f, type_t *t, int declonly) write_namespace_start(f, t->namespace); } indent(f, 0); - write_type_left(f, &ds, NAME_DEFAULT, declonly, TRUE); + write_type_left(f, &ds, NAME_DEFAULT, define, TRUE); fprintf(f, ";\n"); if(in_namespace) { t->written = save_written; write_namespace_end(f, t->namespace); fprintf(f, "extern "C" {\n"); fprintf(f, "#else\n"); - write_type_left(f, &ds, NAME_C, declonly, 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"); @@ -591,12 +591,12 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name) { - write_type_v(f, t, FALSE, TRUE, name, NAME_DEFAULT); + write_type_v(f, t, FALSE, false, name, NAME_DEFAULT); }
void write_type_decl_left(FILE *f, const decl_spec_t *ds) { - write_type_left(f, ds, NAME_DEFAULT, TRUE, TRUE); + write_type_left(f, ds, NAME_DEFAULT, false, TRUE); }
static int user_type_registered(const char *name) @@ -817,14 +817,14 @@ static void write_generic_handle_routines(FILE *header) } }
-static void write_typedef(FILE *header, type_t *type, int declonly) +static void write_typedef(FILE *header, type_t *type, bool define) { type_t *t = type_alias_get_aliasee_type(type); if (winrt_mode && t->namespace && !is_global_namespace(t->namespace)) { fprintf(header, "#ifndef __cplusplus\n"); fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->c_name, NAME_C); + write_type_v(header, type_alias_get_aliasee(type), FALSE, define, type->c_name, NAME_C); fprintf(header, ";\n"); if (type_get_type_detect_alias(t) != TYPE_ENUM) { @@ -832,7 +832,7 @@ static void write_typedef(FILE *header, type_t *type, int declonly) write_namespace_start(header, t->namespace); indent(header, 0); fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, TRUE, type->name, NAME_DEFAULT); + write_type_v(header, type_alias_get_aliasee(type), FALSE, false, type->name, NAME_DEFAULT); fprintf(header, ";\n"); write_namespace_end(header, t->namespace); } @@ -841,7 +841,7 @@ static void write_typedef(FILE *header, type_t *type, int declonly) else { fprintf(header, "typedef "); - write_type_v(header, type_alias_get_aliasee(type), FALSE, declonly, type->name, NAME_DEFAULT); + write_type_v(header, type_alias_get_aliasee(type), FALSE, define, type->name, NAME_DEFAULT); fprintf(header, ";\n"); } } @@ -886,7 +886,7 @@ static void write_declaration(FILE *header, const var_t *v) fprintf(header, "extern "); break; } - write_type_v(header, &v->declspec, FALSE, v->declonly, v->name, NAME_DEFAULT); + write_type_v(header, &v->declspec, FALSE, v->define, v->name, NAME_DEFAULT); fprintf(header, ";\n\n"); } } @@ -1127,10 +1127,10 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i } else fprintf(h, ","); } - /* In theory we should be writing the definition using write_type_v(..., arg->declonly), + /* 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, TRUE, arg->name, name_type); + write_type_v(h, &arg->declspec, FALSE, false, arg->name, name_type); if (method == 2) { const expr_t *expr = get_attrp(arg->attrs, ATTR_DEFAULTVALUE); if (expr) { @@ -1498,7 +1498,7 @@ static void write_parameterized_type_forward(FILE *header, type_t *type) fprintf(header, "#endif\n\n" ); }
-static void write_parameterized_implementation(FILE *header, type_t *type, int declonly) +static void write_parameterized_implementation(FILE *header, type_t *type, bool define) { const statement_t *stmt; typeref_list_t *params = type->details.parameterized.params; @@ -2006,11 +2006,11 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons 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->declonly); + write_type_definition(header, stmt->u.type, stmt->define); else { is_object_interface++; - write_parameterized_implementation(header, stmt->u.type, stmt->declonly); + write_parameterized_implementation(header, stmt->u.type, stmt->define); is_object_interface--; } break; @@ -2032,7 +2032,7 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons { typeref_t *ref; if (stmt->u.type_list) LIST_FOR_EACH_ENTRY(ref, stmt->u.type_list, typeref_t, entry) - write_typedef(header, ref->type, stmt->declonly); + write_typedef(header, ref->type, stmt->define); break; } case STMT_LIBRARY: diff --git a/tools/widl/header.h b/tools/widl/header.h index ae06d92bfa8..45066898a66 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, int declonly, int write_callconv); +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_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/parser.y b/tools/widl/parser.y index 1fe9e1139c8..61a294b5c31 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -87,7 +87,7 @@ static statement_t *make_statement_pragma(const char *str); static statement_t *make_statement_cppquote(const char *str); static statement_t *make_statement_importlib(const char *str); static statement_t *make_statement_module(type_t *type); -static statement_t *make_statement_typedef(var_list_t *names, int declonly); +static statement_t *make_statement_typedef(var_list_t *names, bool define); static statement_t *make_statement_import(const char *str); static statement_t *make_statement_parameterized_type(type_t *type, typeref_list_t *params); static statement_t *make_statement_delegate(type_t *ret, var_list_t *args); @@ -1359,7 +1359,7 @@ type: typedef: m_attributes tTYPEDEF m_attributes decl_spec declarator_list { $1 = append_attribs($1, $3); reg_typedefs( @$, $4, $5, check_typedef_attrs( $1 ) ); - $$ = make_statement_typedef($5, !$4->type->defined); + $$ = make_statement_typedef($5, $4->type->defined); } ;
@@ -1719,7 +1719,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, declarator v->declspec.type = decl->type; v->declspec.qualifier = decl->qualifier; v->attrs = attrs; - v->declonly = !type->defined; + v->define = type->defined;
if (is_attr(type->attrs, ATTR_CALLCONV) && !is_func(type)) error_loc("calling convention applied to non-function type\n"); @@ -1922,7 +1922,7 @@ var_t *make_var(char *name) v->attrs = NULL; v->eval = NULL; init_location( &v->where, NULL, NULL ); - v->declonly = FALSE; + v->define = true; return v; }
@@ -2756,7 +2756,7 @@ static statement_list_t *append_parameterized_type_stmts(statement_list_t *stmts { case STMT_TYPE: stmt->u.type = type_parameterized_type_specialize_define(stmt->u.type); - stmt->declonly = FALSE; + stmt->define = true; list_remove(&stmt->entry); stmts = append_statement(stmts, stmt); break; @@ -2833,7 +2833,7 @@ static statement_t *make_statement_type_decl(type_t *type) { statement_t *stmt = make_statement(STMT_TYPE); stmt->u.type = type; - stmt->declonly = !type->defined; + stmt->define = type->defined; return stmt; }
@@ -2904,7 +2904,7 @@ static statement_t *make_statement_module(type_t *type) return stmt; }
-static statement_t *make_statement_typedef(declarator_list_t *decls, int declonly) +static statement_t *make_statement_typedef(declarator_list_t *decls, bool define) { declarator_t *decl, *next; statement_t *stmt; @@ -2913,7 +2913,7 @@ static statement_t *make_statement_typedef(declarator_list_t *decls, int declonl
stmt = make_statement(STMT_TYPEDEF); stmt->u.type_list = NULL; - stmt->declonly = declonly; + stmt->define = define;
LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry ) { diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index 9bfec7c5000..0777de77bf0 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -5055,7 +5055,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun if (args) LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry ) { print_file(file, 2, "%s", ""); - write_type_left( file, &arg->declspec, NAME_DEFAULT, TRUE, TRUE ); + write_type_left( file, &arg->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 );
@@ -5071,7 +5071,7 @@ void write_func_param_struct( FILE *file, const type_t *iface, const type_t *fun if (add_retval && !is_void( retval->declspec.type )) { print_file(file, 2, "%s", ""); - write_type_left( file, &retval->declspec, NAME_DEFAULT, TRUE, TRUE ); + write_type_left( file, &retval->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) @@ -5122,9 +5122,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, TRUE, TRUE); + write_type_left(file, &ds, NAME_DEFAULT, false, TRUE); fprintf(file, " *%s = (", var_name); - write_type_left(file, &ds, NAME_DEFAULT, TRUE, 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 */ diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 1a26bb77cad..34b8776e21c 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -22,6 +22,7 @@ #define __WIDL_WIDLTYPES_H
#include <stdarg.h> +#include <stdbool.h> #include <assert.h> #include "ndrtypes.h" #include "wine/list.h" @@ -541,7 +542,8 @@ struct _var_t {
struct location where;
- unsigned int declonly : 1; + /* Should we define the UDT in this var, when writing a header? */ + bool define;
/* parser-internal */ struct list entry; @@ -622,7 +624,9 @@ struct _statement_t { typelib_t *lib; typeref_list_t *type_list; } u; - unsigned int declonly : 1; /* for STMT_TYPE and STMT_TYPEDEF */ + /* For STMT_TYPE and STMT_TYPEDEF, should we define the UDT in this + * statement, when writing a header? */ + bool define; };
struct _warning_t {
From: Elizabeth Figura zfigura@codeweavers.com
--- tools/widl/typetree.c | 95 ++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 65 deletions(-)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 7e4c4fd3a38..1623a2729a6 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -530,6 +530,14 @@ type_t *type_new_void(void) return void_type; }
+static void define_type(type_t *type) +{ + if (type->defined) + error_loc("type %s already defined at %s:%d\n", type->name, type->where.input_name, type->where.first_line ); + + type->defined = TRUE; +} + type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums) { type_t *t = NULL; @@ -546,14 +554,12 @@ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined reg_type(t, name, namespace, tsENUM); }
- if (!t->defined && defined) + if (defined) { t->details.enumeration = xmalloc(sizeof(*t->details.enumeration)); t->details.enumeration->enums = enums; - t->defined = TRUE; + define_type(t); } - else if (defined) - error_loc("redefinition of enum %s\n", name);
return t; } @@ -574,14 +580,12 @@ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, va reg_type(t, name, namespace, tsSTRUCT); }
- if (!t->defined && defined) + if (defined) { t->details.structure = xmalloc(sizeof(*t->details.structure)); t->details.structure->fields = fields; - t->defined = TRUE; + define_type(t); } - else if (defined) - error_loc("redefinition of struct %s\n", name);
return t; } @@ -606,10 +610,8 @@ type_t *type_new_nonencapsulated_union(const char *name, struct namespace *names { t->details.structure = xmalloc(sizeof(*t->details.structure)); t->details.structure->fields = fields; - t->defined = TRUE; + define_type(t); } - else if (defined) - error_loc("redefinition of union %s\n", name);
return t; } @@ -630,19 +632,14 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio } t->type_type = TYPE_ENCAPSULATED_UNION;
- if (!t->defined) - { - if (!union_field) - union_field = make_var(xstrdup("tagged_union")); - union_field->declspec.type = type_new_nonencapsulated_union(gen_name(), NULL, TRUE, cases); + if (!union_field) + union_field = make_var(xstrdup("tagged_union")); + union_field->declspec.type = type_new_nonencapsulated_union(gen_name(), NULL, TRUE, cases);
- t->details.structure = xmalloc(sizeof(*t->details.structure)); - t->details.structure->fields = append_var(NULL, switch_field); - t->details.structure->fields = append_var(t->details.structure->fields, union_field); - t->defined = TRUE; - } - else - error_loc("redefinition of union %s\n", name); + t->details.structure = xmalloc(sizeof(*t->details.structure)); + t->details.structure->fields = append_var(NULL, switch_field); + t->details.structure->fields = append_var(t->details.structure->fields, union_field); + define_type(t);
return t; } @@ -732,9 +729,6 @@ type_t *type_interface_declare(char *name, struct namespace *namespace)
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, typeref_list_t *requires) { - if (iface->defined) - error_loc( "interface %s already defined at %s:%d\n", iface->name, - iface->where.input_name, iface->where.first_line ); if (iface == inherit) error_loc("interface %s can't inherit from itself\n", iface->name); @@ -747,7 +741,7 @@ type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit iface->details.iface->disp_inherit = NULL; iface->details.iface->async_iface = NULL; iface->details.iface->requires = requires; - iface->defined = TRUE; + define_type(iface); compute_method_indexes(iface); return iface; } @@ -763,9 +757,6 @@ type_t *type_dispinterface_declare(char *name)
type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t *props, var_list_t *methods) { - if (iface->defined) - error_loc( "dispinterface %s already defined at %s:%d\n", iface->name, - iface->where.input_name, iface->where.first_line ); iface->attrs = check_dispiface_attrs(iface->name, attrs); iface->details.iface = xmalloc(sizeof(*iface->details.iface)); iface->details.iface->disp_props = props; @@ -776,16 +767,13 @@ type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t iface->details.iface->disp_inherit = NULL; iface->details.iface->async_iface = NULL; iface->details.iface->requires = NULL; - iface->defined = TRUE; + define_type(iface); compute_method_indexes(iface); return iface; }
type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *attrs, type_t *iface) { - if (dispiface->defined) - error_loc( "dispinterface %s already defined at %s:%d\n", dispiface->name, - dispiface->where.input_name, dispiface->where.first_line ); dispiface->attrs = check_dispiface_attrs(dispiface->name, attrs); dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface)); dispiface->details.iface->disp_props = NULL; @@ -796,7 +784,7 @@ type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *att dispiface->details.iface->disp_inherit = iface; dispiface->details.iface->async_iface = NULL; dispiface->details.iface->requires = NULL; - dispiface->defined = TRUE; + define_type(dispiface); compute_method_indexes(dispiface); return dispiface; } @@ -812,13 +800,10 @@ type_t *type_module_declare(char *name)
type_t *type_module_define(type_t* module, attr_list_t *attrs, statement_list_t *stmts) { - if (module->defined) - error_loc( "module %s already defined at %s:%d\n", module->name, - module->where.input_name, module->where.first_line ); module->attrs = check_module_attrs(module->name, attrs); module->details.module = xmalloc(sizeof(*module->details.module)); module->details.module->stmts = stmts; - module->defined = TRUE; + define_type(module); return module; }
@@ -833,12 +818,9 @@ type_t *type_coclass_declare(char *name)
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, typeref_list_t *ifaces) { - if (coclass->defined) - error_loc( "coclass %s already defined at %s:%d\n", coclass->name, - coclass->where.input_name, coclass->where.first_line ); coclass->attrs = check_coclass_attrs(coclass->name, attrs); coclass->details.coclass.ifaces = ifaces; - coclass->defined = TRUE; + define_type(coclass); return coclass; }
@@ -856,12 +838,9 @@ type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, typer typeref_t *ref, *required, *tmp; typeref_list_t *requires;
- if (runtimeclass->defined) - error_loc( "runtimeclass %s already defined at %s:%d\n", runtimeclass->name, - runtimeclass->where.input_name, runtimeclass->where.first_line ); runtimeclass->attrs = check_runtimeclass_attrs(runtimeclass->name, attrs); runtimeclass->details.runtimeclass.ifaces = ifaces; - runtimeclass->defined = TRUE; + define_type(runtimeclass); if (!type_runtimeclass_get_default_iface(runtimeclass, FALSE) && !get_attrp(runtimeclass->attrs, ATTR_STATIC)) error_loc("runtimeclass %s must have a default interface or static factory\n", runtimeclass->name); @@ -901,11 +880,8 @@ type_t *type_apicontract_declare(char *name, struct namespace *namespace)
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs) { - if (apicontract->defined) - error_loc( "apicontract %s already defined at %s:%d\n", apicontract->name, - apicontract->where.input_name, apicontract->where.first_line ); apicontract->attrs = check_apicontract_attrs(apicontract->name, attrs); - apicontract->defined = TRUE; + define_type(apicontract); return apicontract; }
@@ -934,10 +910,6 @@ type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_lis { type_t *iface;
- if (delegate->defined) - error_loc( "delegate %s already defined at %s:%d\n", delegate->name, - delegate->where.input_name, delegate->where.first_line ); - delegate->attrs = check_interface_attrs(delegate->name, attrs);
iface = make_type(TYPE_INTERFACE); @@ -955,7 +927,7 @@ type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_lis compute_method_indexes(iface);
delegate->details.delegate.iface = iface; - delegate->defined = TRUE; + define_type(delegate); compute_delegate_iface_names(delegate, NULL, NULL);
return delegate; @@ -975,9 +947,6 @@ type_t *type_parameterized_interface_declare(char *name, struct namespace *names type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, typeref_list_t *requires) { type_t *iface; - if (type->defined) - error_loc( "pinterface %s already defined at %s:%d\n", type->name, - type->where.input_name, type->where.first_line );
/* The parameterized type UUID is actually a PIID that is then used as a seed to generate * a new type GUID with the rules described in: @@ -998,7 +967,7 @@ type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, ty
iface->name = type->name;
- type->defined = TRUE; + define_type(type); return type; }
@@ -1017,10 +986,6 @@ type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs, sta { type_t *iface, *delegate;
- if (type->defined) - error_loc( "pdelegate %s already defined at %s:%d\n", type->name, - type->where.input_name, type->where.first_line ); - type->attrs = check_interface_attrs(type->name, attrs);
delegate = type->details.parameterized.type; @@ -1041,7 +1006,7 @@ type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs, sta delegate->name = type->name; compute_delegate_iface_names(delegate, type, type->details.parameterized.params);
- type->defined = TRUE; + define_type(type); return type; }
From: Elizabeth Figura zfigura@codeweavers.com
This improves error reporting for the following IDL:
interface apple;
[uuid(12345678-1234-1234-1234-123456654321)] interface apple {void func(void);} [uuid(12345678-1234-1234-1234-123456654321)] interface apple {void func(void);}
Previously widl would report:
test2.idl:19:34: error: type apple already defined at test2.idl:2
This changes it to refer to line 5, where the interface is actually defined. --- tools/widl/typetree.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 1623a2729a6..34579e4584f 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -536,6 +536,7 @@ static void define_type(type_t *type) error_loc("type %s already defined at %s:%d\n", type->name, type->where.input_name, type->where.first_line );
type->defined = TRUE; + init_location(&type->where, NULL, NULL); }
type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
From: Elizabeth Figura zfigura@codeweavers.com
midl does not, and this would result in redefinition errors.
An equivalent (and arguably a bit more declarative) way to do this would be to keep track in the parser whether a type or typedef statement is actually a definition or not, and record that information in the statement_t. However, this would require passing additional information alongside the type_t from each relevant bison rule, which would thrash a lot of code. --- tools/widl/parser.y | 6 +++--- tools/widl/typetree.c | 2 ++ tools/widl/widltypes.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index 61a294b5c31..44fe7634fdf 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -1359,7 +1359,7 @@ type: typedef: m_attributes tTYPEDEF m_attributes decl_spec declarator_list { $1 = append_attribs($1, $3); reg_typedefs( @$, $4, $5, check_typedef_attrs( $1 ) ); - $$ = make_statement_typedef($5, $4->type->defined); + $$ = make_statement_typedef($5, $4->type->defined && !$4->type->defined_in_import); } ;
@@ -1719,7 +1719,7 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, declarator v->declspec.type = decl->type; v->declspec.qualifier = decl->qualifier; v->attrs = attrs; - v->define = type->defined; + v->define = type->defined && !type->defined_in_import;
if (is_attr(type->attrs, ATTR_CALLCONV) && !is_func(type)) error_loc("calling convention applied to non-function type\n"); @@ -2833,7 +2833,7 @@ static statement_t *make_statement_type_decl(type_t *type) { statement_t *stmt = make_statement(STMT_TYPE); stmt->u.type = type; - stmt->define = type->defined; + stmt->define = type->defined && !type->defined_in_import; return stmt; }
diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index 34579e4584f..bb7f719f8a2 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -536,6 +536,7 @@ static void define_type(type_t *type) error_loc("type %s already defined at %s:%d\n", type->name, type->where.input_name, type->where.first_line );
type->defined = TRUE; + type->defined_in_import = parse_only; init_location(&type->where, NULL, NULL); }
@@ -924,6 +925,7 @@ type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_lis iface->details.iface->disp_inherit = NULL; iface->details.iface->async_iface = NULL; iface->details.iface->requires = NULL; + define_type(iface); iface->defined = TRUE; compute_method_indexes(iface);
diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 34b8776e21c..ac38c0e1139 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -523,6 +523,7 @@ struct _type_t { struct location where; unsigned int ignore : 1; unsigned int defined : 1; + unsigned int defined_in_import : 1; unsigned int written : 1; unsigned int user_types_registered : 1; unsigned int tfswrite : 1; /* if the type needs to be written to the TFS */