diff --git a/tools/widl/parser.y b/tools/widl/parser.y index db4fdb253ad..5008a35f64f 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -98,7 +98,6 @@ static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs); -static attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs); static attr_list_t *check_apicontract_attrs(const char *name, attr_list_t *attrs); const char *get_attr_display_name(enum attr_type type); static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func); @@ -306,7 +305,7 @@ static typelib_t *current_typelib; %type m_abstract_declarator abstract_declarator abstract_declarator_no_direct abstract_direct_declarator %type declarator_list struct_declarator_list %type coclass coclassdef -%type runtimeclass runtimeclass_hdr runtimeclass_def +%type runtimeclass runtimeclass_def %type apicontract %type contract_ver %type pointer_type threading_type marshaling_behavior version @@ -905,22 +904,12 @@ coclassdef: attributes coclass '{' class_interfaces '}' semicolon_opt ; runtimeclass: - tRUNTIMECLASS aIDENTIFIER { $$ = type_new_runtimeclass($2, current_namespace); } - | tRUNTIMECLASS aKNOWNTYPE { $$ = find_type($2, NULL, 0); - if (type_get_type_detect_alias($$) != TYPE_RUNTIMECLASS) - error_loc("%s was not declared a runtimeclass at %s:%d\n", $2, - $$->loc_info.input_name, $$->loc_info.line_number); - } + tRUNTIMECLASS aIDENTIFIER { $$ = type_runtimeclass_declare($2, current_namespace); } + | tRUNTIMECLASS aKNOWNTYPE { $$ = type_runtimeclass_declare($2, current_namespace); } ; -runtimeclass_hdr: attributes runtimeclass { $$ = $2; - check_def($$); - $$->attrs = check_runtimeclass_attrs($2->name, $1); - } - ; - -runtimeclass_def: runtimeclass_hdr '{' class_interfaces '}' semicolon_opt - { $$ = type_runtimeclass_define($1, $3); } +runtimeclass_def: attributes runtimeclass '{' class_interfaces '}' semicolon_opt + { $$ = type_runtimeclass_define($2, $1, $4); } ; apicontract: attributes tAPICONTRACT aIDENTIFIER '{' '}' @@ -2529,7 +2518,7 @@ attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs) return attrs; } -static attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs) +attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs) { const attr_t *attr; if (!attrs) return attrs; diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index cfd186fb02b..825348ddef4 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -205,17 +205,6 @@ type_t *type_new_module(char *name) return type; } -type_t *type_new_runtimeclass(char *name, struct namespace *namespace) -{ - type_t *type = get_type(TYPE_RUNTIMECLASS, name, NULL, 0); - if (type->type_type != TYPE_RUNTIMECLASS || type->defined) - error_loc("%s: redefinition error; original definition was at %s:%d\n", - type->name, type->loc_info.input_name, type->loc_info.line_number); - type->name = name; - type->namespace = namespace; - return type; -} - type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr, unsigned int dim, expr_t *size_is, expr_t *length_is) { @@ -522,8 +511,21 @@ type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *i return coclass; } -type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces) +type_t *type_runtimeclass_declare(char *name, struct namespace *namespace) { + type_t *type = get_type(TYPE_RUNTIMECLASS, name, namespace, 0); + if (type_get_type_detect_alias(type) != TYPE_RUNTIMECLASS) + error_loc("runtimeclass %s previously not declared a runtimeclass at %s:%d\n", + type->name, type->loc_info.input_name, type->loc_info.line_number); + return type; +} + +type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_list_t *ifaces) +{ + if (runtimeclass->defined) + error_loc("runtimeclass %s already defined at %s:%d\n", + runtimeclass->name, runtimeclass->loc_info.input_name, runtimeclass->loc_info.line_number); + runtimeclass->attrs = check_runtimeclass_attrs(runtimeclass->name, attrs); runtimeclass->details.runtimeclass.ifaces = ifaces; runtimeclass->defined = TRUE; if (!type_runtimeclass_get_default_iface(runtimeclass)) diff --git a/tools/widl/typetree.h b/tools/widl/typetree.h index 69d00dee49b..8a8e1c529ac 100644 --- a/tools/widl/typetree.h +++ b/tools/widl/typetree.h @@ -30,6 +30,7 @@ enum name_type { }; attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs); +attr_list_t *check_runtimeclass_attrs(const char *name, attr_list_t *attrs); type_t *type_new_function(var_list_t *args); type_t *type_new_pointer(type_t *ref); @@ -46,13 +47,13 @@ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, va type_t *type_new_nonencapsulated_union(const char *name, 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_bitfield(type_t *field_type, const expr_t *bits); -type_t *type_new_runtimeclass(char *name, struct namespace *namespace); +type_t *type_runtimeclass_declare(char *name, struct namespace *namespace); void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts); void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods); void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface); void type_module_define(type_t *module, statement_list_t *stmts); type_t *type_coclass_define(type_t *coclass, attr_list_t *attrs, ifref_list_t *ifaces); -type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces); +type_t *type_runtimeclass_define(type_t *runtimeclass, attr_list_t *attrs, ifref_list_t *ifaces); int type_is_equal(const type_t *type1, const type_t *type2); const char *type_get_name(const type_t *type, enum name_type name_type); char *gen_name(void);