From a16f4805d80563c3f0aaf1fd20ba5420af9ee9c2 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Thu, 25 Sep 2025 23:27:05 -0700 Subject: [PATCH 1/9] Move setting F_name_generic to fcfmt.py Also set the value on fmt_func instead of fmt_result since the function is generic and not the result. --- docs/reference.rst | 2 ++ regression/reference/generic-cfi/generic.json | 3 +-- regression/reference/generic/generic.json | 3 +-- regression/reference/struct-c/struct.json | 9 +++------ regression/reference/struct-cxx/struct.json | 9 +++------ shroud/fcfmt.py | 4 ++++ shroud/wrapf.py | 4 +--- 7 files changed, 15 insertions(+), 19 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index 48840b6ec..c0dba8db5 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -1416,6 +1416,8 @@ F_name_function Defaults to evaluation of option *F_name_function_template*. F_name_generic + The generic name for a function. + Set with option **class_ctor* or *F_create_generic*. Defaults to evaluation of option *F_name_generic_template*. F_name_impl diff --git a/regression/reference/generic-cfi/generic.json b/regression/reference/generic-cfi/generic.json index 5f6075836..3d3c62535 100644 --- a/regression/reference/generic-cfi/generic.json +++ b/regression/reference/generic-cfi/generic.json @@ -5774,7 +5774,6 @@ "C_return_type": "void", "F_arg_c_call": "SHT_rv%cxxmem", "F_arguments": "", - "F_name_generic": "struct_as_class", "F_subprogram": "function", "c_abstract_decl": "GEN_StructAsClass *", "c_const": "", @@ -5831,7 +5830,7 @@ "C_name_api": "CreateStructAsClass", "F_name_api": "create_struct_as_class", "F_name_function": "create_struct_as_class", - "F_name_generic": "create_struct_as_class", + "F_name_generic": "struct_as_class", "F_name_impl": "create_struct_as_class", "f_arglist": [ "SHT_rv" diff --git a/regression/reference/generic/generic.json b/regression/reference/generic/generic.json index 8b1b036a1..8ab8a6ed5 100644 --- a/regression/reference/generic/generic.json +++ b/regression/reference/generic/generic.json @@ -6389,7 +6389,6 @@ "C_return_type": "void", "F_arg_c_call": "SHT_rv%cxxmem", "F_arguments": "", - "F_name_generic": "struct_as_class", "F_subprogram": "function", "c_abstract_decl": "GEN_StructAsClass *", "c_const": "", @@ -6446,7 +6445,7 @@ "C_name_api": "CreateStructAsClass", "F_name_api": "create_struct_as_class", "F_name_function": "create_struct_as_class", - "F_name_generic": "create_struct_as_class", + "F_name_generic": "struct_as_class", "F_name_impl": "create_struct_as_class", "f_arglist": [ "SHT_rv" diff --git a/regression/reference/struct-c/struct.json b/regression/reference/struct-c/struct.json index 02e9fec5a..178a9675e 100644 --- a/regression/reference/struct-c/struct.json +++ b/regression/reference/struct-c/struct.json @@ -5204,7 +5204,6 @@ "C_return_type": "void", "F_arg_c_call": "SHT_rv%cxxmem", "F_arguments": "", - "F_name_generic": "cstruct_as_class", "F_subprogram": "function", "c_abstract_decl": "STR_Cstruct_as_class *", "c_const": "", @@ -5261,7 +5260,7 @@ "C_name_api": "Create_Cstruct_as_class", "F_name_api": "create_cstruct_as_class", "F_name_function": "create_cstruct_as_class", - "F_name_generic": "create_cstruct_as_class", + "F_name_generic": "cstruct_as_class", "F_name_impl": "create_cstruct_as_class", "f_arglist": [ "SHT_rv" @@ -5329,7 +5328,6 @@ "C_return_type": "void", "F_arg_c_call": "x,\t y,\t SHT_rv%cxxmem", "F_arguments": "x,\t y", - "F_name_generic": "cstruct_as_class", "F_subprogram": "function", "c_abstract_decl": "STR_Cstruct_as_class *", "c_const": "", @@ -5480,7 +5478,7 @@ "C_name_api": "Create_Cstruct_as_class_args", "F_name_api": "create_cstruct_as_class_args", "F_name_function": "create_cstruct_as_class_args", - "F_name_generic": "create_cstruct_as_class_args", + "F_name_generic": "cstruct_as_class", "F_name_impl": "create_cstruct_as_class_args", "f_arglist": [ "SHT_rv", @@ -6045,7 +6043,6 @@ "C_return_type": "void", "F_arg_c_call": "x,\t y,\t z,\t SHT_rv%cxxmem", "F_arguments": "x,\t y,\t z", - "F_name_generic": "cstruct_as_subclass", "F_subprogram": "function", "c_abstract_decl": "STR_Cstruct_as_subclass *", "c_const": "", @@ -6243,7 +6240,7 @@ "C_name_api": "Create_Cstruct_as_subclass_args", "F_name_api": "create_cstruct_as_subclass_args", "F_name_function": "create_cstruct_as_subclass_args", - "F_name_generic": "create_cstruct_as_subclass_args", + "F_name_generic": "cstruct_as_subclass", "F_name_impl": "create_cstruct_as_subclass_args", "f_arglist": [ "SHT_rv", diff --git a/regression/reference/struct-cxx/struct.json b/regression/reference/struct-cxx/struct.json index fe26feb1f..558d42229 100644 --- a/regression/reference/struct-cxx/struct.json +++ b/regression/reference/struct-cxx/struct.json @@ -6249,7 +6249,6 @@ "C_return_type": "void", "F_arg_c_call": "SHT_rv%cxxmem", "F_arguments": "", - "F_name_generic": "cstruct_as_class", "F_subprogram": "function", "c_abstract_decl": "STR_Cstruct_as_class *", "c_const": "", @@ -6306,7 +6305,7 @@ "C_name_api": "Create_Cstruct_as_class", "F_name_api": "create_cstruct_as_class", "F_name_function": "create_cstruct_as_class", - "F_name_generic": "create_cstruct_as_class", + "F_name_generic": "cstruct_as_class", "F_name_impl": "create_cstruct_as_class", "c_arglist": [ "SHC_rv" @@ -6506,7 +6505,6 @@ "C_return_type": "void", "F_arg_c_call": "x,\t y,\t SHT_rv%cxxmem", "F_arguments": "x,\t y", - "F_name_generic": "cstruct_as_class", "F_subprogram": "function", "c_abstract_decl": "STR_Cstruct_as_class *", "c_const": "", @@ -6657,7 +6655,7 @@ "C_name_api": "Create_Cstruct_as_class_args", "F_name_api": "create_cstruct_as_class_args", "F_name_function": "create_cstruct_as_class_args", - "F_name_generic": "create_cstruct_as_class_args", + "F_name_generic": "cstruct_as_class", "F_name_impl": "create_cstruct_as_class_args", "c_arglist": [ "SHC_rv", @@ -7595,7 +7593,6 @@ "C_return_type": "void", "F_arg_c_call": "x,\t y,\t z,\t SHT_rv%cxxmem", "F_arguments": "x,\t y,\t z", - "F_name_generic": "cstruct_as_subclass", "F_subprogram": "function", "c_abstract_decl": "STR_Cstruct_as_subclass *", "c_const": "", @@ -7793,7 +7790,7 @@ "C_name_api": "Create_Cstruct_as_subclass_args", "F_name_api": "create_cstruct_as_subclass_args", "F_name_function": "create_cstruct_as_subclass_args", - "F_name_generic": "create_cstruct_as_subclass_args", + "F_name_generic": "cstruct_as_subclass", "F_name_impl": "create_cstruct_as_subclass_args", "c_arglist": [ "SHC_rv", diff --git a/shroud/fcfmt.py b/shroud/fcfmt.py index b94a91478..8167afbe1 100644 --- a/shroud/fcfmt.py +++ b/shroud/fcfmt.py @@ -147,6 +147,10 @@ def fmt_function(self, wlang, cls, node): fmt_result = statements.set_bind_fmtdict(bind_result, fmt_func) if wlang == "f": + if node.options.class_ctor: + # Generic constructor for C "class" (wrap_struct_as=class). + clsnode = node.lookup_class(node.options.class_ctor) + fmt_func.F_name_generic = clsnode.fmtdict.F_derived_name node.eval_template("F_name_impl") node.eval_template("F_name_function") node.eval_template("F_name_generic") diff --git a/shroud/wrapf.py b/shroud/wrapf.py index a10e5b5c3..48e9def08 100644 --- a/shroud/wrapf.py +++ b/shroud/wrapf.py @@ -1603,10 +1603,8 @@ def wrap_function_impl(self, cls, node, fileinfo): if node.options.class_ctor: # Generic constructor for C "class" (wrap_struct_as=class). - clsnode = node.lookup_class(node.options.class_ctor) - fmt_result.F_name_generic = clsnode.fmtdict.F_derived_name fileinfo.f_function_generic.setdefault( - fmt_result.F_name_generic, GenericFunction(True, cls, []) + fmt_func.F_name_generic, GenericFunction(True, cls, []) ).functions.append(node) elif options.F_create_generic: # if return type is templated in C++, From 78e748cce5cc1ffc2ae4ef63999d6a20f75e838f Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Thu, 25 Sep 2025 23:47:05 -0700 Subject: [PATCH 2/9] Use F_name_generic from fmt_func instead of fmt_result It is only set on fmt_func now. fmt_result worked since its parent is fmt_func. --- shroud/wrapf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shroud/wrapf.py b/shroud/wrapf.py index 48e9def08..23c57a4f1 100644 --- a/shroud/wrapf.py +++ b/shroud/wrapf.py @@ -1614,12 +1614,12 @@ def wrap_function_impl(self, cls, node, fileinfo): # ctor generic do not get added as derived type generic. # Always create a generic, even if only one function. fileinfo.f_function_generic.setdefault( - fmt_result.F_name_generic, GenericFunction(True, cls, []) + fmt_func.F_name_generic, GenericFunction(True, cls, []) ).functions.append(node) else: if cls: fileinfo.f_type_generic.setdefault( - fmt_result.F_name_generic, GenericFunction(False, cls, []) + fmt_func.F_name_generic, GenericFunction(False, cls, []) ).functions.append(node) # If from a fortran_generic list, create generic interface. if node._generated == "fortran_generic": @@ -1627,7 +1627,7 @@ def wrap_function_impl(self, cls, node, fileinfo): else: force = False fileinfo.f_function_generic.setdefault( - fmt_result.F_name_scope + fmt_result.F_name_generic, + fmt_func.F_name_scope + fmt_func.F_name_generic, GenericFunction(force, cls, [])).functions.append(node) if cls: # Add procedure to derived type From c08d10bac9af40b8d5913f226e56335c5a3a5856 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Thu, 25 Sep 2025 23:59:18 -0700 Subject: [PATCH 3/9] Set F_name_generic for is_ctor in fcfmt.py Moved from generate.py --- shroud/fcfmt.py | 4 +++- shroud/generate.py | 1 - 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/shroud/fcfmt.py b/shroud/fcfmt.py index 8167afbe1..2ae68e079 100644 --- a/shroud/fcfmt.py +++ b/shroud/fcfmt.py @@ -147,7 +147,9 @@ def fmt_function(self, wlang, cls, node): fmt_result = statements.set_bind_fmtdict(bind_result, fmt_func) if wlang == "f": - if node.options.class_ctor: + if node.ast.declarator.is_ctor: + fmt_func.F_name_generic = fmt_func.F_derived_name + elif node.options.class_ctor: # Generic constructor for C "class" (wrap_struct_as=class). clsnode = node.lookup_class(node.options.class_ctor) fmt_func.F_name_generic = clsnode.fmtdict.F_derived_name diff --git a/shroud/generate.py b/shroud/generate.py index 6c47312d1..7214ecada 100644 --- a/shroud/generate.py +++ b/shroud/generate.py @@ -759,7 +759,6 @@ def define_function_suffix(self, functions): overloaded_functions.setdefault(name, []).append( function) function.options.F_create_generic = True - fmt.F_name_generic = name function._overloaded = True else: overloaded_functions.setdefault(function.name, []).append( From 096df587bc3b9fb121d94e858f75fa9015c15bf7 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Fri, 26 Sep 2025 00:14:10 -0700 Subject: [PATCH 4/9] Reorder code Have fcfmt.py match wrapf.py --- shroud/fcfmt.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/shroud/fcfmt.py b/shroud/fcfmt.py index 2ae68e079..0a3b81b74 100644 --- a/shroud/fcfmt.py +++ b/shroud/fcfmt.py @@ -147,12 +147,12 @@ def fmt_function(self, wlang, cls, node): fmt_result = statements.set_bind_fmtdict(bind_result, fmt_func) if wlang == "f": - if node.ast.declarator.is_ctor: - fmt_func.F_name_generic = fmt_func.F_derived_name - elif node.options.class_ctor: + if node.options.class_ctor: # Generic constructor for C "class" (wrap_struct_as=class). clsnode = node.lookup_class(node.options.class_ctor) fmt_func.F_name_generic = clsnode.fmtdict.F_derived_name + elif node.ast.declarator.is_ctor: + fmt_func.F_name_generic = fmt_func.F_derived_name node.eval_template("F_name_impl") node.eval_template("F_name_function") node.eval_template("F_name_generic") From f9ce0eacc2cc6f89b0c285458391d2ef410ed621 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Fri, 26 Sep 2025 00:39:29 -0700 Subject: [PATCH 5/9] Update F_name_generic in fcfmt.py Use reeval_template to avoid the inlocal in eval_template. It is only called when needed instead of for each function. Since options.F_create_generic is tested before setting, it is no longer set for functions which are templated on their result (since Fortran cannot create a generic interface for those functions). This changes some JSON files. Update from user_fmt after function_fmt is set since F_name_generic may be set in the YAML file by the user. --- regression/reference/cdesc/cdesc.json | 2 -- regression/reference/debugfalse/tutorial.json | 2 -- regression/reference/example/example.json | 2 -- regression/reference/templates/templates.json | 6 ------ regression/reference/tutorial/tutorial.json | 2 -- shroud/fcfmt.py | 10 +++++++--- 6 files changed, 7 insertions(+), 17 deletions(-) diff --git a/regression/reference/cdesc/cdesc.json b/regression/reference/cdesc/cdesc.json index 0096908a4..a88d84317 100644 --- a/regression/reference/cdesc/cdesc.json +++ b/regression/reference/cdesc/cdesc.json @@ -1281,7 +1281,6 @@ "C_name_api": "getData", "F_name_api": "get_data", "F_name_function": "get_data_int", - "F_name_generic": "get_data", "F_name_impl": "get_data_int", "c_arglist": [ "SHC_rv" @@ -1445,7 +1444,6 @@ "C_name_api": "getData", "F_name_api": "get_data", "F_name_function": "get_data_double", - "F_name_generic": "get_data", "F_name_impl": "get_data_double", "c_arglist": [ "SHC_rv" diff --git a/regression/reference/debugfalse/tutorial.json b/regression/reference/debugfalse/tutorial.json index 91a5600da..89f869f8c 100644 --- a/regression/reference/debugfalse/tutorial.json +++ b/regression/reference/debugfalse/tutorial.json @@ -3560,7 +3560,6 @@ "C_name_api": "TemplateReturn", "F_name_api": "template_return", "F_name_function": "template_return_int", - "F_name_generic": "template_return", "F_name_impl": "template_return_int", "c_arglist": [ "SHC_rv" @@ -3723,7 +3722,6 @@ "C_name_api": "TemplateReturn", "F_name_api": "template_return", "F_name_function": "template_return_double", - "F_name_generic": "template_return", "F_name_impl": "template_return_double", "c_arglist": [ "SHC_rv" diff --git a/regression/reference/example/example.json b/regression/reference/example/example.json index aa4c2da9f..26fdb8c3a 100644 --- a/regression/reference/example/example.json +++ b/regression/reference/example/example.json @@ -6491,7 +6491,6 @@ "C_name_api": "getValue", "F_name_api": "get_value", "F_name_function": "get_value_int", - "F_name_generic": "get_value", "F_name_impl": "ex_class2_get_value_int", "LUA_name": "getValue", "LUA_name_api": "getValue", @@ -6724,7 +6723,6 @@ "C_name_api": "getValue", "F_name_api": "get_value", "F_name_function": "get_value_double", - "F_name_generic": "get_value", "F_name_impl": "ex_class2_get_value_double", "PY_name_impl": "PP_getValue_double", "c_arglist": [ diff --git a/regression/reference/templates/templates.json b/regression/reference/templates/templates.json index 880e836a7..8b1fc8340 100644 --- a/regression/reference/templates/templates.json +++ b/regression/reference/templates/templates.json @@ -1453,7 +1453,6 @@ "C_name_api": "get_value", "F_name_api": "get_value", "F_name_function": "get_value", - "F_name_generic": "get_value", "F_name_impl": "struct_as_class_int_get_value", "c_arglist": [ "SHC_rv" @@ -2397,7 +2396,6 @@ "C_name_api": "get_value", "F_name_api": "get_value", "F_name_function": "get_value", - "F_name_generic": "get_value", "F_name_impl": "struct_as_class_double_get_value", "c_arglist": [ "SHC_rv" @@ -3841,7 +3839,6 @@ "C_name_api": "UseImplWorker", "F_name_api": "use_impl_worker", "F_name_function": "use_impl_worker_internal_ImplWorker1", - "F_name_generic": "use_impl_worker", "F_name_impl": "use_impl_worker_internal_ImplWorker1", "PY_name_impl": "PY_UseImplWorker_internal_ImplWorker1", "c_arglist": [ @@ -4041,7 +4038,6 @@ "C_name_api": "UseImplWorker", "F_name_api": "use_impl_worker", "F_name_function": "use_impl_worker_internal_ImplWorker2", - "F_name_generic": "use_impl_worker", "F_name_impl": "use_impl_worker_internal_ImplWorker2", "PY_name_impl": "PY_UseImplWorker_internal_ImplWorker2", "c_arglist": [ @@ -5045,7 +5041,6 @@ "C_name_api": "at", "F_name_api": "at", "F_name_function": "at", - "F_name_generic": "at", "F_name_impl": "vector_int_at", "PY_name_impl": "PY_at", "c_arglist": [ @@ -6141,7 +6136,6 @@ "C_name_api": "at", "F_name_api": "at", "F_name_function": "at", - "F_name_generic": "at", "F_name_impl": "vector_double_at", "PY_name_impl": "PY_at", "c_arglist": [ diff --git a/regression/reference/tutorial/tutorial.json b/regression/reference/tutorial/tutorial.json index 91a5600da..89f869f8c 100644 --- a/regression/reference/tutorial/tutorial.json +++ b/regression/reference/tutorial/tutorial.json @@ -3560,7 +3560,6 @@ "C_name_api": "TemplateReturn", "F_name_api": "template_return", "F_name_function": "template_return_int", - "F_name_generic": "template_return", "F_name_impl": "template_return_int", "c_arglist": [ "SHC_rv" @@ -3723,7 +3722,6 @@ "C_name_api": "TemplateReturn", "F_name_api": "template_return", "F_name_function": "template_return_double", - "F_name_generic": "template_return", "F_name_impl": "template_return_double", "c_arglist": [ "SHC_rv" diff --git a/shroud/fcfmt.py b/shroud/fcfmt.py index 0a3b81b74..314c728c1 100644 --- a/shroud/fcfmt.py +++ b/shroud/fcfmt.py @@ -139,6 +139,7 @@ def fmt_function(self, wlang, cls, node): cursor = self.cursor func_cursor = cursor.push_node(node) + options = node.options fmt_func = node.fmtdict arglist = [] setattr(fmt_func, "{}_arglist".format(wlang), arglist) @@ -151,11 +152,14 @@ def fmt_function(self, wlang, cls, node): # Generic constructor for C "class" (wrap_struct_as=class). clsnode = node.lookup_class(node.options.class_ctor) fmt_func.F_name_generic = clsnode.fmtdict.F_derived_name - elif node.ast.declarator.is_ctor: - fmt_func.F_name_generic = fmt_func.F_derived_name + elif options.F_create_generic: + if node.ast.declarator.is_ctor: + fmt_func.F_name_generic = fmt_func.F_derived_name + else: + node.reeval_template("F_name_generic") node.eval_template("F_name_impl") node.eval_template("F_name_function") - node.eval_template("F_name_generic") + fmt_func.update(node.user_fmt) result_stmt = bind_result.stmt func_cursor.stmt = result_stmt From e93b9b939b2e7af19ddd65fe756c3bbbca265a28 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Fri, 26 Sep 2025 00:56:49 -0700 Subject: [PATCH 6/9] Use reeval_template instead of eval_template fmt_func is updated form user_fmt afterwards so the user values is take priority. Working to remove inlocal if possible. --- shroud/fcfmt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shroud/fcfmt.py b/shroud/fcfmt.py index 314c728c1..4cb09d046 100644 --- a/shroud/fcfmt.py +++ b/shroud/fcfmt.py @@ -157,8 +157,8 @@ def fmt_function(self, wlang, cls, node): fmt_func.F_name_generic = fmt_func.F_derived_name else: node.reeval_template("F_name_generic") - node.eval_template("F_name_impl") - node.eval_template("F_name_function") + node.reeval_template("F_name_impl") + node.reeval_template("F_name_function") fmt_func.update(node.user_fmt) result_stmt = bind_result.stmt From 77a568035557555648a1155a16b6dcdfcb728db1 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Sat, 27 Sep 2025 18:53:36 -0700 Subject: [PATCH 7/9] Compute TypedefNode.fmtdict in fcfmt.py Before computed in ast.py. user_dict is used to update as the final step. fill_typedef_typemap is then called. update_names is a no-op and can be removed later. Its contents were moved into fcfmt.py. Changes to JSON files: python-only - c_type, C_name_typedef, are no longer defined since it is not going through fcfmt.py templates - std::vector::size_type does not update the typemap, only the instantiations of std::vector. typedefs-c - Properly apply typedef format fields to set C_name_typedef. This propogates to other format fields. --- .../reference/python-only/tutorial.json | 5 ++--- regression/reference/templates/templates.json | 12 +++++------ regression/reference/typedefs-c/typedefs.json | 20 +++++++++--------- shroud/ast.py | 21 ++++++------------- shroud/fcfmt.py | 16 ++++++++++++++ 5 files changed, 40 insertions(+), 34 deletions(-) diff --git a/regression/reference/python-only/tutorial.json b/regression/reference/python-only/tutorial.json index de23a5b5e..1c6077a90 100644 --- a/regression/reference/python-only/tutorial.json +++ b/regression/reference/python-only/tutorial.json @@ -2297,7 +2297,7 @@ "arg": { "fmtdict": { "c_const": "", - "c_type": "TypeID", + "c_type": "", "c_var": "arg", "ctor_expr": "arg", "cxx_addr": "&", @@ -2915,7 +2915,6 @@ }, "zz_fmtdict": { "C_name_api": "TypeID", - "C_name_typedef": "TypeID", "F_name_api": "type_id", "cxx_type": "TypeID", "typedef_name": "TypeID" @@ -3039,7 +3038,7 @@ "PY_format": "i", "PY_get": "PyInt_AsLong({py_var})", "base": "integer", - "c_type": "TypeID", + "c_type": "", "cfi_type": "CFI_type_int", "cxx_type": "tutorial::TypeID", "f_cast": "int({f_var}, )", diff --git a/regression/reference/templates/templates.json b/regression/reference/templates/templates.json index 8b1fc8340..442ae271b 100644 --- a/regression/reference/templates/templates.json +++ b/regression/reference/templates/templates.json @@ -6601,25 +6601,25 @@ "c_header": [ "" ], - "c_type": "TEM_vector_size_type", + "c_type": "", "cfi_type": "CFI_type_size_t", "cxx_header": [ "" ], "cxx_type": "std::vector::size_type", - "f_cast": "int({f_var}, vector_size_type)", - "f_kind": "vector_size_type", + "f_cast": "int({f_var}, )", + "f_kind": "", "f_module": { "templates_std_mod": [ - "vector_size_type" + "" ] }, "f_module_name": "templates_std_mod", - "f_type": "integer(vector_size_type)", + "f_type": "integer()", "flat_name": "size_t", "i_module": { "templates_std_mod": [ - "vector_size_type" + "" ] }, "sgroup": "native", diff --git a/regression/reference/typedefs-c/typedefs.json b/regression/reference/typedefs-c/typedefs.json index 1b8864acb..1ebb6b487 100644 --- a/regression/reference/typedefs-c/typedefs.json +++ b/regression/reference/typedefs-c/typedefs.json @@ -1711,7 +1711,7 @@ "C_call_function": "returnBytesForIndexType2(\targ)", "C_call_list": "arg", "C_name": "returnBytesForIndexType2", - "C_prototype": "IndexType2 arg", + "C_prototype": "LOCAL_IndexType arg", "C_return_type": "int", "F_arg_c_call": "arg", "F_arguments": "arg", @@ -1752,12 +1752,12 @@ }, "arg": { "fmtdict": { - "c_abstract_decl": "IndexType2", + "c_abstract_decl": "LOCAL_IndexType", "c_addr": "&", "c_const": "", "c_deref": "", "c_member": ".", - "c_type": "IndexType2", + "c_type": "LOCAL_IndexType", "c_var": "arg", "cxx_abstract_decl": "IndexType2", "cxx_addr": "&", @@ -1880,14 +1880,14 @@ "C_call_function": "returnShapeSize2(\tndims,\t shape)", "C_call_list": "ndims,\t shape", "C_name": "returnShapeSize2", - "C_prototype": "int ndims,\t const IndexType2 *shape", - "C_return_type": "IndexType2", + "C_prototype": "int ndims,\t const LOCAL_IndexType *shape", + "C_return_type": "LOCAL_IndexType", "F_arg_c_call": "ndims,\t shape", "F_arguments": "ndims,\t shape", "F_subprogram": "function", "c_const": "", "c_get_value": "", - "c_type": "IndexType2", + "c_type": "LOCAL_IndexType", "c_var": "SHC_rv", "cxx_addr": "&", "cxx_member": ".", @@ -1961,12 +1961,12 @@ }, "shape": { "fmtdict": { - "c_abstract_decl": "const IndexType2 *", + "c_abstract_decl": "const LOCAL_IndexType *", "c_addr": "", "c_const": "const ", "c_deref": "*", "c_member": "->", - "c_type": "IndexType2", + "c_type": "LOCAL_IndexType", "c_var": "shape", "cxx_abstract_decl": "const IndexType2 *", "cxx_addr": "", @@ -2340,7 +2340,7 @@ }, "zz_fmtdict": { "C_name_api": "IndexType2", - "C_name_typedef": "IndexType2", + "C_name_typedef": "LOCAL_IndexType", "F_name_api": "index_type2", "F_name_typedef": "LOCAL_Index_Type", "cxx_type": "IndexType2", @@ -2523,7 +2523,7 @@ "c_header": [ "" ], - "c_type": "IndexType2", + "c_type": "LOCAL_IndexType", "cfi_type": "CFI_type_int32_t", "cxx_header": [ "" diff --git a/shroud/ast.py b/shroud/ast.py index 63cd989b0..0d59be26c 100644 --- a/shroud/ast.py +++ b/shroud/ast.py @@ -1914,6 +1914,12 @@ class TypedefNode(AstNode): Typedef. Includes builtin typedefs and from declarations. + YAML file + - decl: typedef long SidreLength + fields: + c_header : sidre/SidreTypes.h + c_type : SIDRE_SidreLength + type name must be in a typemap. - decl: typedef int IndexType @@ -1952,9 +1958,6 @@ def __init__(self, name, parent, ast, fields, self.fmtdict = util.Scope(parent.fmtdict) self.user_fmt = format self.default_format(parent, format) - if self.user_fmt: - self.fmtdict.update(self.user_fmt, replace=True) - self.update_names() self.ast = ast self.user_fields = fields @@ -1990,16 +1993,6 @@ def update_names(self): Called when reading declaration and when instantiation a class in GenFunctions.template_typedef. """ - fmt = self.fmtdict - if self.wrap.c: - if "C_name_typedef" not in self.user_fmt: - self.reeval_template("C_name_typedef") - else: - # language=c, use original name. - fmt.C_name_typedef = fmt.typedef_name - if self.wrap.fortran: - if "F_name_typedef" not in self.user_fmt: - self.reeval_template("F_name_typedef") def clone(self): """Create a copy of a TypedefNode to use with C++ template. @@ -2018,14 +2011,12 @@ def clone_post_class(self, targs): Need to create a new typemap for typedefs within a templated class. """ - self.update_names() type_name = util.wformat("{namespace_scope}{class_scope}{cxx_type}", self.fmtdict) ntypemap = self.typemap.clone_as(type_name) self.typemap = ntypemap self.parent.symtab.register_typemap(type_name, ntypemap) ntypemap.is_typedef = True - typemap.fill_typedef_typemap(self) ###################################################################### diff --git a/shroud/fcfmt.py b/shroud/fcfmt.py index 4cb09d046..df71259da 100644 --- a/shroud/fcfmt.py +++ b/shroud/fcfmt.py @@ -10,6 +10,7 @@ from .declstr import gen_arg_as_c, gen_arg_as_cxx from . import todict from . import statements +from . import typemap from . import util from .util import wformat, append_format @@ -91,6 +92,9 @@ def wrap_class(self, node): fmt_class = node.fmtdict cls_cursor = self.cursor.push_node(node) + for typ in node.typedefs: + self.fmt_typedefs(typ) + if node.baseclass: # Only single inheritance supported. # Base class already contains F_derived_member. @@ -108,6 +112,18 @@ def wrap_class(self, node): self.cursor.pop_node(node) def fmt_typedefs(self, node): + fmt = node.fmtdict + if node.wrap.c: + node.reeval_template("C_name_typedef") + else: + # language=c, use original name. + fmt.C_name_typedef = fmt.typedef_name + if node.wrap.fortran: + node.reeval_template("F_name_typedef") + + fmt.update(node.user_fmt) + typemap.fill_typedef_typemap(node, node.user_fields) + if node.wrap.fortran: if node.ast.declarator.is_function_pointer(): meta = statements.fetch_typedef_bind(node, "f").meta From b27ede2e562941288e425aafd407752205e57b67 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Sat, 27 Sep 2025 19:01:09 -0700 Subject: [PATCH 8/9] Remove update_names method The work is now done in fcfmt.py. --- shroud/ast.py | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/shroud/ast.py b/shroud/ast.py index 0d59be26c..6a64ed1e2 100644 --- a/shroud/ast.py +++ b/shroud/ast.py @@ -174,13 +174,6 @@ def apply_LUA_API_option(self, name): case = self.options.LUA_API_case return self.apply_API_option(name, case, "LUA_API_case") - def update_names(self): - """Update C and Fortran names. - Necessary after templates are instantiated which - defines fmt.function_suffix. - """ - raise NotImplementedError("update_names for {}".format(self.__class__.__name__)) - ###################################################################### class NamespaceMixin(object): @@ -1987,13 +1980,6 @@ def default_format(self, parent, format): F_name_api = self.apply_F_API_option(self.name), ) - def update_names(self): - """Update C and Fortran names. - - Called when reading declaration and - when instantiation a class in GenFunctions.template_typedef. - """ - def clone(self): """Create a copy of a TypedefNode to use with C++ template. """ From 4e1cc46d3a577945604db59dfc1b10354c5db7d7 Mon Sep 17 00:00:00 2001 From: Lee Taylor Date: Tue, 30 Sep 2025 10:45:36 -0700 Subject: [PATCH 9/9] Only call fill_typedef_typemap from fcfmt.py It was being called from ast.py earlier. Now it is called after templates are instantiated in generate.py. Added test error-fmt and moved some tests from error-ast. error-ast is correctly stopping because of errors and never calls fill_typedef_typemap from its new location. Test error-fmt has no AST errors. Changes to JSON files. python-only - Fills in fields in typedef TypeID. c_type is unchanged when created by declast.py since fill_typedef_typemap is no longer called where C_name_typedef is unset. templates - Fills in fields in uninstantiated std::vector::size_type --- regression/do-test.py | 2 + regression/input/error-ast.yaml | 11 -- regression/input/error-fmt.yaml | 27 ++++ regression/reference/error-ast/output | 17 +-- regression/reference/error-fmt/error-fmt.json | 123 +++++++++++++++++ regression/reference/error-fmt/error-fmt.log | 9 ++ regression/reference/error-fmt/output | 17 +++ .../reference/error-fmt/pyerrormodule.cpp | 125 ++++++++++++++++++ .../reference/error-fmt/pyerrormodule.hpp | 29 ++++ regression/reference/error-fmt/setup.py | 25 ++++ regression/reference/error-fmt/typeserror.h | 35 +++++ regression/reference/error-fmt/utilerror.cpp | 25 ++++ regression/reference/error-fmt/wraperror.h | 38 ++++++ regression/reference/error-fmt/wrapferror.f | 35 +++++ .../reference/python-only/tutorial.json | 26 ++-- regression/reference/templates/templates.json | 24 ++-- shroud/ast.py | 5 +- shroud/fcfmt.py | 2 + 18 files changed, 516 insertions(+), 59 deletions(-) create mode 100644 regression/input/error-fmt.yaml create mode 100644 regression/reference/error-fmt/error-fmt.json create mode 100644 regression/reference/error-fmt/error-fmt.log create mode 100644 regression/reference/error-fmt/output create mode 100644 regression/reference/error-fmt/pyerrormodule.cpp create mode 100644 regression/reference/error-fmt/pyerrormodule.hpp create mode 100644 regression/reference/error-fmt/setup.py create mode 100644 regression/reference/error-fmt/typeserror.h create mode 100644 regression/reference/error-fmt/utilerror.cpp create mode 100644 regression/reference/error-fmt/wraperror.h create mode 100644 regression/reference/error-fmt/wrapferror.f diff --git a/regression/do-test.py b/regression/do-test.py index 5c0fb1a04..1160c00ea 100644 --- a/regression/do-test.py +++ b/regression/do-test.py @@ -612,6 +612,8 @@ def __init__(self, name, yaml=None, cmdline=None, keywords=[]): keywords=["err"]), TestDesc("error-ast", keywords=["err"]), + TestDesc("error-fmt", + keywords=["err"]), TestDesc("error-generate", keywords=["err"]), ] diff --git a/regression/input/error-ast.yaml b/regression/input/error-ast.yaml index c63988552..a53976634 100644 --- a/regression/input/error-ast.yaml +++ b/regression/input/error-ast.yaml @@ -120,17 +120,6 @@ declarations: #### # -- decl: typedef int64_t IndexType - fields: - # Unknown key for Typemap 'no_such_keyword' - no_such_keyword: True - f_c_module: - "--import--": - - LIB_IndexType - -#### -# - - decl: template struct twostruct diff --git a/regression/input/error-fmt.yaml b/regression/input/error-fmt.yaml new file mode 100644 index 000000000..2ba127c95 --- /dev/null +++ b/regression/input/error-fmt.yaml @@ -0,0 +1,27 @@ +copyright: +- Copyright Shroud Project Developers. See LICENSE file for details. +- +- "SPDX-License-Identifier: (BSD-3-Clause)" +- + +# Test error messages from fcfmt.py. + +library: error +cxx_header: error.hpp + +options: + debug: True + wrap_python: True + +declarations: + +#### +# + +- decl: typedef int64_t IndexType + fields: + # Unknown key for Typemap 'no_such_keyword' + no_such_keyword: True + f_c_module: + "--import--": + - LIB_IndexType diff --git a/regression/reference/error-ast/output b/regression/reference/error-ast/output index 9761b0a87..08811eee3 100644 --- a/regression/reference/error-ast/output +++ b/regression/reference/error-ast/output @@ -108,28 +108,21 @@ Error in 'decl' field ^ Expected EOF, found ID -------------------- -Node: IndexType -Typemap IndexType: Unknown key 'no_such_keyword' --------------------- -Node: IndexType -typedef int64_t IndexType -Deprecated: Typemap IndexType: Replacing deprecated field 'f_c_module' with 'i_module' --------------------- Node: process_twostruct -line 137 +line 126 Templated function requires the 'cxx_template' field -------------------- Node: process_twostruct -line 137 +line 126 field f_arg_decl is deprecated, changed to f_dummy_decl -------------------- Node: process_twostruct -line 145 +line 134 'cxx_template' field only used with a templated function -------------------- Node: getConstCharPtrAsCopyArg -line 153 +line 142 format F_string_result_as_arg is deprecated, changed to option.F_result_as_arg Instead add attribute +funcarg(name)+deref(copy) to decl. Option F_result_as_arg is the default name when not specified in +funcarg. -Too many warnings: 30 +Too many warnings: 29 diff --git a/regression/reference/error-fmt/error-fmt.json b/regression/reference/error-fmt/error-fmt.json new file mode 100644 index 000000000..a18a5d4f1 --- /dev/null +++ b/regression/reference/error-fmt/error-fmt.json @@ -0,0 +1,123 @@ +{ + "": "This file is generated by Shroud nowrite-version and is useful for debugging.", + "library": { + "copyright": [ + "Copyright Shroud Project Developers. See LICENSE file for details.", + "", + "SPDX-License-Identifier: (BSD-3-Clause)", + "" + ], + "cxx_header": [ + "error.hpp" + ], + "language": "cxx", + "scope_file": [ + "error" + ], + "typedefs": [ + { + "": "IndexType ****************************************", + "ast": { + "declarator": { + "name": "IndexType", + "typemap_name": "int64_t" + }, + "specifier": [ + "int64_t" + ], + "storage": [ + "typedef" + ], + "typemap_name": "IndexType" + }, + "f_kind": "C_INT64_T", + "f_module": { + "iso_c_binding": [ + "C_INT64_T" + ] + }, + "name": "IndexType", + "options": {}, + "user_fields": { + "f_c_module": { + "--import--": [ + "LIB_IndexType" + ] + }, + "no_such_keyword": true + }, + "wrap": { + "c": true, + "fortran": true, + "python": true + }, + "zz_bind": { + "c": { + "IndexType": {} + }, + "f": { + "IndexType": {} + }, + "share": { + "IndexType": {} + } + }, + "zz_fmtdict": { + "C_name_api": "IndexType", + "C_name_typedef": "ERR_IndexType", + "F_name_api": "index_type", + "F_name_typedef": "index_type", + "cxx_type": "IndexType", + "typedef_name": "IndexType" + } + } + ], + "wrap": { + "c": true, + "fortran": true, + "python": true + } + }, + "types": { + "IndexType": { + "LUA_pop": "lua_tointeger({LUA_state_var}, {LUA_index})", + "LUA_push": "lua_pushinteger({LUA_state_var}, {push_arg})", + "LUA_type": "LUA_TNUMBER", + "PYN_typenum": "NPY_INT64", + "PY_ctor": "PyInt_FromLong({ctor_expr})", + "PY_format": "L", + "PY_get": "PyInt_AsLong({py_var})", + "base": "integer", + "c_header": [ + "" + ], + "c_type": "ERR_IndexType", + "cfi_type": "CFI_type_int64_t", + "cxx_header": [ + "" + ], + "cxx_type": "IndexType", + "f_cast": "int({f_var}, index_type)", + "f_kind": "index_type", + "f_module": { + "error_mod": [ + "index_type" + ] + }, + "f_module_name": "error_mod", + "f_type": "integer(index_type)", + "flat_name": "int64_t", + "i_module": { + "--import--": [ + "LIB_IndexType" + ] + }, + "sgroup": "native", + "sh_type": "SH_TYPE_INT64_T", + "typedef": "int64_t", + "wrap_header": [ + "wraperror.h" + ] + } + } +} \ No newline at end of file diff --git a/regression/reference/error-fmt/error-fmt.log b/regression/reference/error-fmt/error-fmt.log new file mode 100644 index 000000000..c91cf10f9 --- /dev/null +++ b/regression/reference/error-fmt/error-fmt.log @@ -0,0 +1,9 @@ +Read yaml error-fmt.yaml +Close wraperror.h +typedef IndexType +Close wrapferror.f +Close utilerror.cpp +Close typeserror.h +Close pyerrormodule.cpp +Close pyerrormodule.hpp +Close setup.py diff --git a/regression/reference/error-fmt/output b/regression/reference/error-fmt/output new file mode 100644 index 000000000..0761a742d --- /dev/null +++ b/regression/reference/error-fmt/output @@ -0,0 +1,17 @@ + +---------------------------------------- +Phase: FillFormat typedef +---------------------------------------- +Node: IndexType +Typemap IndexType: Unknown key 'no_such_keyword' +-------------------- +Node: IndexType +typedef int64_t IndexType +Deprecated: Typemap IndexType: Replacing deprecated field 'f_c_module' with 'i_module' +Wrote wraperror.h +Wrote wrapferror.f +Wrote utilerror.cpp +Wrote typeserror.h +Wrote pyerrormodule.cpp +Wrote pyerrormodule.hpp +Wrote setup.py diff --git a/regression/reference/error-fmt/pyerrormodule.cpp b/regression/reference/error-fmt/pyerrormodule.cpp new file mode 100644 index 000000000..edd780b5c --- /dev/null +++ b/regression/reference/error-fmt/pyerrormodule.cpp @@ -0,0 +1,125 @@ +// pyerrormodule.cpp +// This file is generated by Shroud nowrite-version. Do not edit. +// Copyright Shroud Project Developers. See LICENSE file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) +// +#include "pyerrormodule.hpp" + +// splicer begin include +// splicer end include + +#ifdef __cplusplus +#define SHROUD_UNUSED(param) +#else +#define SHROUD_UNUSED(param) param +#endif + +#if PY_MAJOR_VERSION >= 3 +#define PyInt_AsLong PyLong_AsLong +#define PyInt_FromLong PyLong_FromLong +#define PyInt_FromSize_t PyLong_FromSize_t +#define PyString_FromString PyUnicode_FromString +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#endif + +// splicer begin C_definition +// splicer end C_definition +PyObject *PY_error_obj; + +// splicer begin additional_functions +// splicer end additional_functions +static PyMethodDef PY_methods[] = { +{nullptr, (PyCFunction)nullptr, 0, nullptr} /* sentinel */ +}; + +/* + * initerror - Initialization function for the module + * *must* be called initerror + */ +static char PY__doc__[] = +"library documentation" +; + +struct module_state { + PyObject *error; +}; + +#if PY_MAJOR_VERSION >= 3 +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) +#else +#define GETSTATE(m) (&_state) +static struct module_state _state; +#endif + +#if PY_MAJOR_VERSION >= 3 +static int error_traverse(PyObject *m, visitproc visit, void *arg) { + Py_VISIT(GETSTATE(m)->error); + return 0; +} + +static int error_clear(PyObject *m) { + Py_CLEAR(GETSTATE(m)->error); + return 0; +} + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "error", /* m_name */ + PY__doc__, /* m_doc */ + sizeof(struct module_state), /* m_size */ + PY_methods, /* m_methods */ + nullptr, /* m_reload */ + error_traverse, /* m_traverse */ + error_clear, /* m_clear */ + NULL /* m_free */ +}; + +#define RETVAL m +#define INITERROR return nullptr +#else +#define RETVAL +#define INITERROR return +#endif + +extern "C" PyMODINIT_FUNC +#if PY_MAJOR_VERSION >= 3 +PyInit_error(void) +#else +initerror(void) +#endif +{ + PyObject *m = nullptr; + const char * error_name = "error.Error"; + + // splicer begin C_init_locals + // splicer end C_init_locals + + + /* Create the module and add the functions */ +#if PY_MAJOR_VERSION >= 3 + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule4("error", PY_methods, + PY__doc__, + (PyObject*)nullptr,PYTHON_API_VERSION); +#endif + if (m == nullptr) + return RETVAL; + struct module_state *st = GETSTATE(m); + + PY_error_obj = PyErr_NewException((char *) error_name, nullptr, nullptr); + if (PY_error_obj == nullptr) + return RETVAL; + st->error = PY_error_obj; + PyModule_AddObject(m, "Error", st->error); + + // splicer begin C_init_body + // splicer end C_init_body + + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module error"); + return RETVAL; +} + diff --git a/regression/reference/error-fmt/pyerrormodule.hpp b/regression/reference/error-fmt/pyerrormodule.hpp new file mode 100644 index 000000000..9c48cfdc4 --- /dev/null +++ b/regression/reference/error-fmt/pyerrormodule.hpp @@ -0,0 +1,29 @@ +// pyerrormodule.hpp +// This file is generated by Shroud nowrite-version. Do not edit. +// Copyright Shroud Project Developers. See LICENSE file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) +// +#ifndef PYERRORMODULE_HPP +#define PYERRORMODULE_HPP + +#include + +// cxx_header +#include "error.hpp" + +// splicer begin header.include +// splicer end header.include + +// splicer begin header.C_declaration +// splicer end header.C_declaration + +extern PyObject *PY_error_obj; + +#if PY_MAJOR_VERSION >= 3 +extern "C" PyMODINIT_FUNC PyInit_error(void); +#else +extern "C" PyMODINIT_FUNC initerror(void); +#endif + +#endif /* PYERRORMODULE_HPP */ diff --git a/regression/reference/error-fmt/setup.py b/regression/reference/error-fmt/setup.py new file mode 100644 index 000000000..9e62ee413 --- /dev/null +++ b/regression/reference/error-fmt/setup.py @@ -0,0 +1,25 @@ +# setup.py +# This file is generated by Shroud nowrite-version. Do not edit. +# Copyright Shroud Project Developers. See LICENSE file for details. +# +# SPDX-License-Identifier: (BSD-3-Clause) +# +from setuptools import setup, Extension + +module = Extension( + 'error', + sources=[ + 'pyerrormodule.cpp' + ], + language='c++', + include_dirs = None, +# libraries = ['tcl83'], +# library_dirs = ['/usr/local/lib'], +# extra_compile_args = [ '-O0', '-g' ], +# extra_link_args = +) + +setup( + name='error', + ext_modules = [module], +) diff --git a/regression/reference/error-fmt/typeserror.h b/regression/reference/error-fmt/typeserror.h new file mode 100644 index 000000000..4698903c3 --- /dev/null +++ b/regression/reference/error-fmt/typeserror.h @@ -0,0 +1,35 @@ +// typeserror.h +// This file is generated by Shroud nowrite-version. Do not edit. +// Copyright Shroud Project Developers. See LICENSE file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) +// +// For C users and C++ implementation + +#ifndef TYPESERROR_H +#define TYPESERROR_H + +// splicer begin types.CXX_declarations +// splicer end types.CXX_declarations + +#ifdef __cplusplus +extern "C" { +#endif + +// splicer begin types.C_declarations +// splicer end types.C_declarations + +// helper capsule_data_helper +struct s_ERR_SHROUD_capsule_data { + void *addr; /* address of C++ memory */ + int idtor; /* index of destructor */ +}; +typedef struct s_ERR_SHROUD_capsule_data ERR_SHROUD_capsule_data; + +void ERR_SHROUD_memory_destructor(ERR_SHROUD_capsule_data *cap); + +#ifdef __cplusplus +} +#endif + +#endif // TYPESERROR_H diff --git a/regression/reference/error-fmt/utilerror.cpp b/regression/reference/error-fmt/utilerror.cpp new file mode 100644 index 000000000..0578916e4 --- /dev/null +++ b/regression/reference/error-fmt/utilerror.cpp @@ -0,0 +1,25 @@ +// utilerror.cpp +// This file is generated by Shroud nowrite-version. Do not edit. +// Copyright Shroud Project Developers. See LICENSE file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) +// + +// shroud +#include "typeserror.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +// Release library allocated memory. +void ERR_SHROUD_memory_destructor(ERR_SHROUD_capsule_data *cap) +{ + cap->addr = nullptr; + cap->idtor = 0; // avoid deleting again +} + +#ifdef __cplusplus +} +#endif diff --git a/regression/reference/error-fmt/wraperror.h b/regression/reference/error-fmt/wraperror.h new file mode 100644 index 000000000..6f229a697 --- /dev/null +++ b/regression/reference/error-fmt/wraperror.h @@ -0,0 +1,38 @@ +// wraperror.h +// This file is generated by Shroud nowrite-version. Do not edit. +// Copyright Shroud Project Developers. See LICENSE file for details. +// +// SPDX-License-Identifier: (BSD-3-Clause) +// +/** + * \file wraperror.h + * \brief Shroud generated wrapper for error library + */ +// For C users and C++ implementation + +#ifndef WRAPERROR_H +#define WRAPERROR_H + +// shroud +#include "typeserror.h" + +// splicer begin CXX_declarations +// splicer end CXX_declarations + +#ifdef __cplusplus +extern "C" { +#endif + +// splicer begin C_declarations +// splicer end C_declarations + +// typedef IndexType +// splicer begin typedef.IndexType +typedef int64_t ERR_IndexType; +// splicer end typedef.IndexType + +#ifdef __cplusplus +} +#endif + +#endif // WRAPERROR_H diff --git a/regression/reference/error-fmt/wrapferror.f b/regression/reference/error-fmt/wrapferror.f new file mode 100644 index 000000000..463dfef1c --- /dev/null +++ b/regression/reference/error-fmt/wrapferror.f @@ -0,0 +1,35 @@ +! wrapferror.f +! This file is generated by Shroud nowrite-version. Do not edit. +! Copyright Shroud Project Developers. See LICENSE file for details. +! +! SPDX-License-Identifier: (BSD-3-Clause) +! +!> +!! \file wrapferror.f +!! \brief Shroud generated wrapper for error library +!< +! splicer begin file_top +! splicer end file_top +module error_mod + use iso_c_binding, only : C_INT64_T + ! splicer begin module_use + ! splicer end module_use + implicit none + + ! splicer begin module_top + ! splicer end module_top + + ! typedef IndexType + ! splicer begin typedef.IndexType + integer, parameter :: index_type = C_INT64_T + ! splicer end typedef.IndexType + + ! splicer begin additional_declarations + ! splicer end additional_declarations + +contains + + ! splicer begin additional_functions + ! splicer end additional_functions + +end module error_mod diff --git a/regression/reference/python-only/tutorial.json b/regression/reference/python-only/tutorial.json index 1c6077a90..3a263bb8d 100644 --- a/regression/reference/python-only/tutorial.json +++ b/regression/reference/python-only/tutorial.json @@ -2297,7 +2297,7 @@ "arg": { "fmtdict": { "c_const": "", - "c_type": "", + "c_type": "int", "c_var": "arg", "ctor_expr": "arg", "cxx_addr": "&", @@ -3038,30 +3038,22 @@ "PY_format": "i", "PY_get": "PyInt_AsLong({py_var})", "base": "integer", - "c_type": "", + "c_type": "int", "cfi_type": "CFI_type_int", "cxx_type": "tutorial::TypeID", - "f_cast": "int({f_var}, )", - "f_kind": "", + "f_cast": "int({f_var}, C_INT)", + "f_kind": "C_INT", "f_module": { - "tutorial_mod": [ - "" + "iso_c_binding": [ + "C_INT" ] }, - "f_module_name": "tutorial_mod", - "f_type": "integer()", + "f_module_name": "iso_c_binding", + "f_type": "integer(C_INT)", "flat_name": "int", - "i_module": { - "tutorial_mod": [ - "" - ] - }, "sgroup": "native", "sh_type": "SH_TYPE_INT", - "typedef": "int", - "wrap_header": [ - "wrapTutorial.h" - ] + "typedef": "int" } } } \ No newline at end of file diff --git a/regression/reference/templates/templates.json b/regression/reference/templates/templates.json index 442ae271b..525f649a6 100644 --- a/regression/reference/templates/templates.json +++ b/regression/reference/templates/templates.json @@ -6601,33 +6601,25 @@ "c_header": [ "" ], - "c_type": "", + "c_type": "size_t", "cfi_type": "CFI_type_size_t", "cxx_header": [ "" ], "cxx_type": "std::vector::size_type", - "f_cast": "int({f_var}, )", - "f_kind": "", + "f_cast": "int({f_var}, C_SIZE_T)", + "f_kind": "C_SIZE_T", "f_module": { - "templates_std_mod": [ - "" + "iso_c_binding": [ + "C_SIZE_T" ] }, - "f_module_name": "templates_std_mod", - "f_type": "integer()", + "f_module_name": "iso_c_binding", + "f_type": "integer(C_SIZE_T)", "flat_name": "size_t", - "i_module": { - "templates_std_mod": [ - "" - ] - }, "sgroup": "native", "sh_type": "SH_TYPE_SIZE_T", - "typedef": "size_t", - "wrap_header": [ - "wrapstd_vector.h" - ] + "typedef": "size_t" }, "std::vector::size_type": { "LUA_pop": "lua_tointeger({LUA_state_var}, {LUA_index})", diff --git a/shroud/ast.py b/shroud/ast.py index 6a64ed1e2..e43b9e720 100644 --- a/shroud/ast.py +++ b/shroud/ast.py @@ -799,6 +799,7 @@ def default_format(self, fmtdict, kwargs): # Add default values to format to aid debugging. # Avoids exception from wformat for non-existent fields. fmt_library.update(dict( + C_name_typedef="XXXC_name_typedef", c_get_value="XXXc_get_value", c_type="XXXc_type", c_var="XXXc_var", @@ -814,6 +815,7 @@ def default_format(self, fmtdict, kwargs): cxx_type="XXXcxx_type", cxx_var="XXXcxx_var", # cxx_T="short", # Needs to be a actual type to find helper. + F_name_typedef="XXXF_name_typedef", f_abstract_interface="XXXf_abstract_interface=", f_capsule_data_type="XXXf_capsule_data_type", f_intent="XXXf_intent", @@ -1962,9 +1964,6 @@ def __init__(self, name, parent, ast, fields, self.f_module = ntypemap.f_module self.typemap = ntypemap - typemap.fill_typedef_typemap(self) - if fields: - ntypemap.update(fields) error.cursor.pop_node(self) def get_typename(self): diff --git a/shroud/fcfmt.py b/shroud/fcfmt.py index df71259da..292f6c775 100644 --- a/shroud/fcfmt.py +++ b/shroud/fcfmt.py @@ -112,6 +112,7 @@ def wrap_class(self, node): self.cursor.pop_node(node) def fmt_typedefs(self, node): + self.cursor.push_node(node) fmt = node.fmtdict if node.wrap.c: node.reeval_template("C_name_typedef") @@ -143,6 +144,7 @@ def fmt_typedefs(self, node): # XXX - To be changed to i_module, i_kind fmt.i_module_name = ntypemap.f_module_name fmt.i_kind = ntypemap.f_kind + self.cursor.pop_node(node) def fmt_functions(self, cls, functions): for node in functions: