From 5664851b726b74199e30c060bc06ead4ff0cc507 Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Tue, 15 Aug 2023 14:18:10 +0200 Subject: [PATCH] fix #2878 --- TestSuite/delegates20.pas | 13 ++++++++ TreeConverter/OpenMP/OpenMP.cs | 31 +++++++++++++++++++ .../TreeConversion/syntax_tree_visitor.cs | 8 +++-- 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 TestSuite/delegates20.pas diff --git a/TestSuite/delegates20.pas b/TestSuite/delegates20.pas new file mode 100644 index 000000000..0ab7bbefe --- /dev/null +++ b/TestSuite/delegates20.pas @@ -0,0 +1,13 @@ +type + d1 = Action; + +procedure p0(d: d1) := exit; + +var i: integer; +begin + var d: d1; + //Ошибка: Нельзя преобразовать тип string к byte + d := p->p('abc'); + d((x: string)->begin assert(x = 'abc'); i := 1 end); + assert(i = 1); +end. \ No newline at end of file diff --git a/TreeConverter/OpenMP/OpenMP.cs b/TreeConverter/OpenMP/OpenMP.cs index 9a0a3c521..4d29ce5e1 100644 --- a/TreeConverter/OpenMP/OpenMP.cs +++ b/TreeConverter/OpenMP/OpenMP.cs @@ -1266,6 +1266,37 @@ namespace PascalABCCompiler.TreeConverter return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.IntPtr", sem_type.location), sem_type.location); else if (sem_type is compiled_type_node ctn2 && ctn2.compiled_type == typeof(System.UIntPtr)) return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.UIntPtr", sem_type.location), sem_type.location); + else if (sem_type is common_type_node && (sem_type as common_type_node).IsDelegate) + { + var tn = sem_type as common_type_node; + var invokeMeth = tn.find_first_in_type("Invoke"); + if (invokeMeth != null) + { + var fn = invokeMeth.sym_info as function_node; + PascalABCCompiler.SyntaxTree.procedure_header header; + if (fn.return_value_type != null) + { + header = new PascalABCCompiler.SyntaxTree.function_header(ConvertToSyntaxType(fn.return_value_type)); + } + else + { + header = new PascalABCCompiler.SyntaxTree.procedure_header(); + } + header.parameters = new PascalABCCompiler.SyntaxTree.formal_parameters(); + foreach (var param in fn.parameters) + { + var tparam = new PascalABCCompiler.SyntaxTree.typed_parameters(); + tparam.vars_type = ConvertToSyntaxType(param.type); + tparam.idents = new PascalABCCompiler.SyntaxTree.ident_list(); + tparam.idents.Add(new PascalABCCompiler.SyntaxTree.ident(param.name)); + header.parameters.Add(tparam); + + } + return header; + } + else + return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location); + } else return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location); } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index bcc2f00b9..0093e4d04 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -18764,7 +18764,7 @@ namespace PascalABCCompiler.TreeConverter foreach (SyntaxTree.type_definition id in types) { type_node tn = null; - if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id)) + if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id) && !type_synonym_instancing) tn = delegate_cache[id]; else tn = convert_strong(id); @@ -18773,7 +18773,7 @@ namespace PascalABCCompiler.TreeConverter { AddError(get_location(id), "TYPE_NAME_EXPECTED"); } - if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id)) + if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id) && !type_synonym_instancing) { delegate_cache[id] = tn; } @@ -18934,6 +18934,8 @@ namespace PascalABCCompiler.TreeConverter return t; } + bool type_synonym_instancing = false; + public common_type_node instance(template_class tc, List template_params, location loc, template_type_reference used_ttr = null) { //Проверяем, что попытка инстанцирования корректна @@ -19093,7 +19095,9 @@ namespace PascalABCCompiler.TreeConverter prm.source_context = loc; } } + type_synonym_instancing = true; type_node synonym_value = convert_strong(tc.type_dec.type_def); + type_synonym_instancing = false; foreach (type_definition td in saved_sc_dict.Keys) td.source_context = saved_sc_dict[td]; ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name,