widl: Update the type location in define_type().

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.
This commit is contained in:
Elizabeth Figura 2024-03-25 18:26:42 -05:00 committed by Alexandre Julliard
parent 1522d7b727
commit 1db2eaf0b3
3 changed files with 92 additions and 65 deletions

View file

@ -500,11 +500,11 @@ warnings:
typedecl:
enumdef
| tENUM typename { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
| tENUM typename { $$ = type_new_enum($2, current_namespace, FALSE, NULL, &@$); }
| structdef
| tSTRUCT typename { $$ = type_new_struct($2, current_namespace, FALSE, NULL); }
| tSTRUCT typename { $$ = type_new_struct($2, current_namespace, FALSE, NULL, &@$); }
| uniondef
| tUNION typename { $$ = 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); }
@ -823,7 +823,7 @@ enum: enum_member '=' expr_int_const { $$ = reg_const($1);
}
;
enumdef: tENUM m_typename '{' enums '}' { $$ = type_new_enum($2, current_namespace, TRUE, $4); }
enumdef: tENUM m_typename '{' enums '}' { $$ = type_new_enum($2, current_namespace, TRUE, $4, &@2); }
;
m_exprs: m_expr { $$ = append_expr( NULL, $1 ); }
@ -1032,7 +1032,7 @@ coclass: tCOCLASS typename { $$ = type_coclass_declare($2); }
;
coclassdef: attributes coclass '{' class_interfaces '}' semicolon_opt
{ $$ = type_coclass_define($2, $1, $4); }
{ $$ = type_coclass_define($2, $1, $4, &@2); }
;
runtimeclass: tRUNTIMECLASS typename { $$ = type_runtimeclass_declare($2, current_namespace); }
@ -1040,14 +1040,14 @@ runtimeclass: tRUNTIMECLASS typename { $$ = type_runtimeclass_declare($2, curre
runtimeclass_def: attributes runtimeclass inherit '{' class_interfaces '}' semicolon_opt
{ if ($3 && type_get_type($3) != TYPE_RUNTIMECLASS) error_loc("%s is not a runtimeclass\n", $3->name);
$$ = type_runtimeclass_define($2, $1, $5); }
$$ = type_runtimeclass_define($2, $1, $5, &@2); }
;
apicontract: tAPICONTRACT typename { $$ = type_apicontract_declare($2, current_namespace); }
;
apicontract_def: attributes apicontract '{' '}' semicolon_opt
{ $$ = type_apicontract_define($2, $1); }
{ $$ = type_apicontract_define($2, $1, &@2); }
;
namespacedef: tNAMESPACE aIDENTIFIER { $$ = append_str( NULL, $2 ); }
@ -1080,9 +1080,9 @@ dispint_meths: tMETHODS ':' { $$ = NULL; }
dispinterfacedef:
dispattributes dispinterface '{' dispint_props dispint_meths '}'
{ $$ = type_dispinterface_define($2, $1, $4, $5); }
{ $$ = type_dispinterface_define($2, $1, $4, $5, &@2); }
| dispattributes dispinterface '{' interface ';' '}'
{ $$ = type_dispinterface_define_from_iface($2, $1, $4); }
{ $$ = type_dispinterface_define_from_iface($2, $1, $4, &@2); }
;
inherit
@ -1107,13 +1107,13 @@ interface:
delegatedef: m_attributes tDELEGATE type ident '(' m_args ')' semicolon_opt
{ $$ = type_delegate_declare($4->name, current_namespace);
$$ = type_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $6)));
$$ = type_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $6)), &@4);
}
| m_attributes tDELEGATE type ident
'<' { push_parameters_namespace($4->name); } type_parameters '>'
'(' m_args ')' { pop_parameters_namespace($4->name); } semicolon_opt
{ $$ = type_parameterized_delegate_declare($4->name, current_namespace, $7);
$$ = type_parameterized_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $10)));
$$ = type_parameterized_delegate_define($$, $1, append_statement(NULL, make_statement_delegate($3, $10)), &@4);
}
;
@ -1133,12 +1133,12 @@ interfacedef: attributes interface { if ($2->type_type == TYPE_PARAMETERIZED_TY
inherit requires '{' int_statements '}' semicolon_opt
{ if ($2->type_type == TYPE_PARAMETERIZED_TYPE)
{
$$ = type_parameterized_interface_define($2, $1, $4, $7, $5);
$$ = type_parameterized_interface_define($2, $1, $4, $7, $5, &@2);
pop_parameters_namespace($2->name);
}
else
{
$$ = type_interface_define($2, $1, $4, $7, $5);
$$ = type_interface_define($2, $1, $4, $7, $5, &@2);
check_async_uuid($$);
}
}
@ -1159,7 +1159,7 @@ module: tMODULE typename { $$ = type_module_declare($2); }
;
moduledef: m_attributes module '{' int_statements '}' semicolon_opt
{ $$ = type_module_define($2, $1, $4); }
{ $$ = type_module_define($2, $1, $4, &@2); }
;
storage_cls_spec:
@ -1334,18 +1334,18 @@ pointer_type:
| tPTR { $$ = FC_FP; }
;
structdef: tSTRUCT m_typename '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4); }
structdef: tSTRUCT m_typename '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4, &@2); }
;
unqualified_type:
tVOID { $$ = type_new_void(); }
| base_type { $$ = $1; }
| enumdef { $$ = $1; }
| tENUM typename { $$ = type_new_enum($2, current_namespace, FALSE, NULL); }
| tENUM typename { $$ = type_new_enum($2, current_namespace, FALSE, NULL, &@$); }
| structdef { $$ = $1; }
| tSTRUCT typename { $$ = type_new_struct($2, current_namespace, FALSE, NULL); }
| tSTRUCT typename { $$ = type_new_struct($2, current_namespace, FALSE, NULL, &@$); }
| uniondef { $$ = $1; }
| tUNION typename { $$ = 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); }
;
@ -1364,10 +1364,10 @@ typedef: m_attributes tTYPEDEF m_attributes decl_spec declarator_list
;
uniondef: tUNION m_typename '{' ne_union_fields '}'
{ $$ = type_new_nonencapsulated_union($2, current_namespace, TRUE, $4); }
{ $$ = type_new_nonencapsulated_union($2, current_namespace, TRUE, $4, &@2); }
| tUNION m_typename
tSWITCH '(' s_field ')'
m_ident '{' cases '}' { $$ = type_new_encapsulated_union($2, $5, $7, $9); }
m_ident '{' cases '}' { $$ = type_new_encapsulated_union($2, $5, $7, $9, &@2); }
;
version:
@ -2742,7 +2742,7 @@ static void check_async_uuid(type_t *iface)
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
type_interface_define(async_iface, map_attrs(iface->attrs, async_iface_attrs), inherit, stmts, NULL);
type_interface_define(async_iface, map_attrs(iface->attrs, async_iface_attrs), inherit, stmts, NULL, &iface->where);
iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface;
}

View file

@ -530,15 +530,17 @@ type_t *type_new_void(void)
return void_type;
}
static void define_type(type_t *type)
static void define_type(type_t *type, const struct location *where)
{
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->where = *where;
}
type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums)
type_t *type_new_enum(const char *name, struct namespace *namespace,
int defined, var_list_t *enums, const struct location *where)
{
type_t *t = NULL;
@ -558,13 +560,14 @@ type_t *type_new_enum(const char *name, struct namespace *namespace, int defined
{
t->details.enumeration = xmalloc(sizeof(*t->details.enumeration));
t->details.enumeration->enums = enums;
define_type(t);
define_type(t, where);
}
return t;
}
type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields)
type_t *type_new_struct(char *name, struct namespace *namespace,
int defined, var_list_t *fields, const struct location *where)
{
type_t *t = NULL;
@ -584,13 +587,14 @@ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, va
{
t->details.structure = xmalloc(sizeof(*t->details.structure));
t->details.structure->fields = fields;
define_type(t);
define_type(t, where);
}
return t;
}
type_t *type_new_nonencapsulated_union(const char *name, struct namespace *namespace, int defined, var_list_t *fields)
type_t *type_new_nonencapsulated_union(const char *name, struct namespace *namespace,
int defined, var_list_t *fields, const struct location *where)
{
type_t *t = NULL;
@ -610,13 +614,14 @@ 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;
define_type(t);
define_type(t, where);
}
return t;
}
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases)
type_t *type_new_encapsulated_union(char *name, var_t *switch_field,
var_t *union_field, var_list_t *cases, const struct location *where)
{
type_t *t = NULL;
@ -634,12 +639,12 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio
if (!union_field)
union_field = make_var(xstrdup("tagged_union"));
union_field->declspec.type = type_new_nonencapsulated_union(gen_name(), NULL, TRUE, cases);
union_field->declspec.type = type_new_nonencapsulated_union(gen_name(), NULL, TRUE, cases, where);
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);
define_type(t, where);
return t;
}
@ -727,7 +732,8 @@ type_t *type_interface_declare(char *name, struct namespace *namespace)
return type;
}
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit, statement_list_t *stmts, typeref_list_t *requires)
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit,
statement_list_t *stmts, typeref_list_t *requires, const struct location *where)
{
if (iface == inherit)
error_loc("interface %s can't inherit from itself\n",
@ -741,7 +747,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;
define_type(iface);
define_type(iface, where);
compute_method_indexes(iface);
return iface;
}
@ -755,7 +761,8 @@ type_t *type_dispinterface_declare(char *name)
return type;
}
type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs, var_list_t *props, var_list_t *methods)
type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs,
var_list_t *props, var_list_t *methods, const struct location *where)
{
iface->attrs = check_dispiface_attrs(iface->name, attrs);
iface->details.iface = xmalloc(sizeof(*iface->details.iface));
@ -767,12 +774,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;
define_type(iface);
define_type(iface, where);
compute_method_indexes(iface);
return iface;
}
type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *attrs, type_t *iface)
type_t *type_dispinterface_define_from_iface(type_t *dispiface,
attr_list_t *attrs, type_t *iface, const struct location *where)
{
dispiface->attrs = check_dispiface_attrs(dispiface->name, attrs);
dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
@ -784,7 +792,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;
define_type(dispiface);
define_type(dispiface, where);
compute_method_indexes(dispiface);
return dispiface;
}
@ -798,12 +806,13 @@ type_t *type_module_declare(char *name)
return type;
}
type_t *type_module_define(type_t* module, attr_list_t *attrs, statement_list_t *stmts)
type_t *type_module_define(type_t* module, attr_list_t *attrs,
statement_list_t *stmts, const struct location *where)
{
module->attrs = check_module_attrs(module->name, attrs);
module->details.module = xmalloc(sizeof(*module->details.module));
module->details.module->stmts = stmts;
define_type(module);
define_type(module, where);
return module;
}
@ -816,11 +825,12 @@ type_t *type_coclass_declare(char *name)
return type;
}
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, typeref_list_t *ifaces)
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs,
typeref_list_t *ifaces, const struct location *where)
{
coclass->attrs = check_coclass_attrs(coclass->name, attrs);
coclass->details.coclass.ifaces = ifaces;
define_type(coclass);
define_type(coclass, where);
return coclass;
}
@ -833,14 +843,15 @@ type_t *type_runtimeclass_declare(char *name, struct namespace *namespace)
return type;
}
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, typeref_list_t *ifaces)
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs,
typeref_list_t *ifaces, const struct location *where)
{
typeref_t *ref, *required, *tmp;
typeref_list_t *requires;
runtimeclass->attrs = check_runtimeclass_attrs(runtimeclass->name, attrs);
runtimeclass->details.runtimeclass.ifaces = ifaces;
define_type(runtimeclass);
define_type(runtimeclass, where);
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);
@ -878,10 +889,10 @@ type_t *type_apicontract_declare(char *name, struct namespace *namespace)
return type;
}
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs)
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs, const struct location *where)
{
apicontract->attrs = check_apicontract_attrs(apicontract->name, attrs);
define_type(apicontract);
define_type(apicontract, where);
return apicontract;
}
@ -906,7 +917,8 @@ type_t *type_delegate_declare(char *name, struct namespace *namespace)
return type;
}
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_list_t *stmts)
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs,
statement_list_t *stmts, const struct location *where)
{
type_t *iface;
@ -927,7 +939,7 @@ type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_lis
compute_method_indexes(iface);
delegate->details.delegate.iface = iface;
define_type(delegate);
define_type(delegate, where);
compute_delegate_iface_names(delegate, NULL, NULL);
return delegate;
@ -944,7 +956,8 @@ type_t *type_parameterized_interface_declare(char *name, struct namespace *names
return type;
}
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 *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit,
statement_list_t *stmts, typeref_list_t *requires, const struct location *where)
{
type_t *iface;
@ -967,7 +980,7 @@ type_t *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, ty
iface->name = type->name;
define_type(type);
define_type(type, where);
return type;
}
@ -982,7 +995,8 @@ type_t *type_parameterized_delegate_declare(char *name, struct namespace *namesp
return type;
}
type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs, statement_list_t *stmts)
type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs,
statement_list_t *stmts, const struct location *where)
{
type_t *iface, *delegate;
@ -1006,7 +1020,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);
define_type(type);
define_type(type, where);
return type;
}

View file

@ -44,28 +44,41 @@ type_t *type_new_basic(enum type_basic_type basic_type);
type_t *type_new_int(enum type_basic_type basic_type, int sign);
type_t *type_new_void(void);
type_t *type_coclass_declare(char *name);
type_t *type_new_enum(const char *name, struct namespace *namespace, int defined, var_list_t *enums);
type_t *type_new_struct(char *name, struct namespace *namespace, int defined, var_list_t *fields);
type_t *type_new_nonencapsulated_union(const char *name, struct namespace *namespace, int defined, var_list_t *fields);
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
type_t *type_new_enum(const char *name, struct namespace *namespace,
int defined, var_list_t *enums, const struct location *where);
type_t *type_new_struct(char *name, struct namespace *namespace,
int defined, var_list_t *fields, const struct location *where);
type_t *type_new_nonencapsulated_union(const char *name, struct namespace *namespace,
int defined, var_list_t *fields, const struct location *where);
type_t *type_new_encapsulated_union(char *name, var_t *switch_field,
var_t *union_field, var_list_t *cases, const struct location *where);
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_runtimeclass_declare(char *name, struct namespace *namespace);
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);
type_t *type_interface_define(type_t *iface, attr_list_t *attrs, type_t *inherit,
statement_list_t *stmts, typeref_list_t *requires, const struct location *where);
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);
type_t *type_dispinterface_define_from_iface(type_t *dispiface, attr_list_t *attrs, type_t *iface);
type_t *type_module_define(type_t* module, attr_list_t *attrs, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, typeref_list_t *ifaces);
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, typeref_list_t *ifaces);
type_t *type_dispinterface_define(type_t *iface, attr_list_t *attrs,
var_list_t *props, var_list_t *methods, const struct location *where);
type_t *type_dispinterface_define_from_iface(type_t *dispiface,
attr_list_t *attrs, type_t *iface, const struct location *where);
type_t *type_module_define(type_t* module, attr_list_t *attrs,
statement_list_t *stmts, const struct location *where);
type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs,
typeref_list_t *ifaces, const struct location *where);
type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs,
typeref_list_t *ifaces, const struct location *where);
type_t *type_apicontract_declare(char *name, struct namespace *namespace);
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs);
type_t *type_apicontract_define(type_t *apicontract, attr_list_t *attrs, const struct location *where);
type_t *type_delegate_declare(char *name, struct namespace *namespace);
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs, statement_list_t *stmts);
type_t *type_delegate_define(type_t *delegate, attr_list_t *attrs,
statement_list_t *stmts, const struct location *where);
type_t *type_parameterized_interface_declare(char *name, struct namespace *namespace, typeref_list_t *params);
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 *type_parameterized_interface_define(type_t *type, attr_list_t *attrs, type_t *inherit,
statement_list_t *stmts, typeref_list_t *requires, const struct location *where);
type_t *type_parameterized_delegate_declare(char *name, struct namespace *namespace, typeref_list_t *params);
type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs, statement_list_t *stmts);
type_t *type_parameterized_delegate_define(type_t *type, attr_list_t *attrs,
statement_list_t *stmts, const struct location *where);
type_t *type_parameterized_type_specialize_partial(type_t *type, typeref_list_t *params);
type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t *params);
type_t *type_parameterized_type_specialize_define(type_t *type);