From: Vibhav Pant vibhavp@gmail.com
--- tools/widl/parser.y | 20 +++++++++++++++++++- tools/widl/typetree.c | 13 +++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y index e57b1412a80..a28fe8c3fee 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -102,6 +102,7 @@ static struct namespace global_namespace = { static struct namespace *current_namespace = &global_namespace; static struct namespace *parameters_namespace = NULL; static statement_list_t *parameterized_type_stmts = NULL; +static statement_list_t *imp_parameterized_type_stmts = NULL;
static typelib_t *current_typelib;
@@ -405,7 +406,9 @@ decl_block: tDECLARE '{' decl_statements '}' { $$ = $3; } imp_decl_statements : %empty { $$ = NULL; } | imp_decl_statements tINTERFACE qualified_type '<' parameterized_type_args '>' ';' - { $$ = append_statement($1, make_statement_reference( @$, type_parameterized_type_specialize_declare($3, $5) )); } + { imp_parameterized_type_stmts = append_statement( imp_parameterized_type_stmts, make_statement_parameterized_type(@$, $3, $5) ); + $$ = append_statement($1, make_statement_reference( @$, type_parameterized_type_specialize_declare($3, $5) )); + } ;
imp_decl_block @@ -2898,6 +2901,21 @@ static statement_list_t *append_parameterized_type_stmts(statement_list_t *stmts { statement_t *stmt, *next;
+ if (imp_parameterized_type_stmts) + LIST_FOR_EACH_ENTRY(stmt, imp_parameterized_type_stmts, statement_t, entry) + { + switch(stmt->type) + { + case STMT_TYPE: + stmt->u.type = type_parameterized_type_specialize_define(stmt->u.type); + stmt->is_defined = 1; + break; + default: + assert(0); + break; + } + } + if (stmts && parameterized_type_stmts) LIST_FOR_EACH_ENTRY_SAFE(stmt, next, parameterized_type_stmts, statement_t, entry) { switch(stmt->type) diff --git a/tools/widl/typetree.c b/tools/widl/typetree.c index c77efbc834f..0f917123ecf 100644 --- a/tools/widl/typetree.c +++ b/tools/widl/typetree.c @@ -1521,11 +1521,20 @@ static void type_parameterized_delegate_specialize(type_t *tmpl, type_t *delegat
type_t *type_parameterized_type_specialize_declare(type_t *type, typeref_list_t *params) { + char *name = format_parameterized_type_name(type, params); type_t *tmpl = type->details.parameterized.type; - type_t *new_type = duptype(tmpl, 0); + type_t *new_type;
+ /* If this specialization has already been registered/declared, reuse it. */ + if ((new_type = find_type(name, type->namespace, 0))) + { + free(name); + return new_type; + } + + new_type = duptype(tmpl, 0); new_type->namespace = type->namespace; - new_type->name = format_parameterized_type_name(type, params); + new_type->name = name; reg_type(new_type, new_type->name, new_type->namespace, 0); new_type->c_name = format_parameterized_type_c_name(type, params, "", "_C"); new_type->short_name = format_parameterized_type_short_name(type, params, "");