Fortran Statements

Note

Work in progress.

Statements are used to add code to the generated wrappers.

The statements work together to pass variables and metadata between Fortran and C.

A Fortran wrapper is created out of several segments.

{} denotes a format field. [] is a statement field.

{F_subprogram} {F_name_impl}({F_arguments}){F_result_clause}
  [f_module]
  [f_dummy_decl]
  ! splicer begin
  [f_local_decl]
  [f_pre_call]
  [f_call]
  [f_post_call]
  ! splicer end
end {F_subprogram} {F_name_impl}

The bind(C) interface is defined by the cstatements since it must match the C wrapper that is being called. The C wrapper may have a different API than the Fortran wrapper since the Fortran may pass down additional arguments.

Format fields

  • F_subprogram

  • F_name_impl

  • F_arguments

  • f_call_function

  • F_result_clause

    For functions, result({F_result}). Evalued after stmt.fmtdict is applied.

  • F_arg_c_call

Statements

name

Must start with a f.

f_dummy_arg

List of dummy argument names for the Fortran subprogram. It will be formatted before being used to expand {f_var}.

Any function result arguments will be added at the end. Only added if f_dummy_decl is also defined.

f_dummy_decl

List of dummy argument declarations or result declarations. Usually constructed from YAML decl but sometimes needs to be explicit to add Fortran attributes such as TARGET or POINTER. Also used when a function result is converted into an argument. Added before splicer since it is part of the API and must not be changed by the splicer. Local variables can be declared with f_local_decl for function results or intermediate values.

f_dummy_arg:
- "{f_var}"
f_dummy_decl:
- character, value, intent(IN) :: {f_var}

It is also used to declare a result defined with f_result_var when converting a subroutine into a function.

f_local_decl

A list of declarations needed by f_pre_call or f_post_call. Usually a c_local_var is sufficient. No executable statements should be used since all declarations must be grouped together. Implies f_need_wrapper. Added within the splicer to make it easier to replace in the YAML file.

f_pre_call

Statement to execute before call, often to coerce types when f_cast cannot be used. Implies f_need_wrapper.

f_arg_call

List of arguments to pass to C wrapper. By default the arguments of the Fortran wrapper are passed to the C wrapper. It will use the f_to_c typemap field if defined. The list of arguments can be set to pass different arguments or expressions. For example, when passing the character length for attribute +api(buf). The format field f_var is the name of the argument.

When used with a f_function statement, the argument will be added to the end of the call list.

f_arg_call:
-  "C_LOC({f_var})"
f_arg_call:
- "{f_var}"
-  "len({f_var}, kind=C_INT)"

To specify no arguments, the list must be blank. Unless the function result has been changed into a C wrapper argument, it will pass no arguments.

f_arg_call: [ ]

The value of None will pass the Fortran argument to the C wrapper.

f_call

Code used to call the function. Defaults to {F_result} = {F_C_call}({f_arg_call})

For example, to assign to an intermediate variable:

f_local_decl:
- "type(C_PTR) :: {c_local_ptr}"
f_call:
- "{c_local_ptr} = {F_C_call}({f_arg_call})"
f_local:
- ptr

f_post_call

Statement to execute after call. Can be use to cleanup after f_pre_call or to coerce the return value. Implies f_need_wrapper.

f_result_var

Name of result variable. Added as the RESULT clause of the subprogram statement. Can be used to change a subroutine into a function by setting the value to as-subroutine (which is an illegal identifier).

In this example, the subroutine is converted into a function which will return the number of items copied into the result argument. f_dummy_decl is used to declare the result variable.

- decl: void vector_iota_out_with_num2(std::vector<int> &arg+intent(out))
  fstatements:
    f:
      f_result_var: num
      f_dummy_decl:
      -  "integer(C_LONG) :: num"
      f_post_call:
      -  "num = SHT_arg_cdesc%size"
      f_module:
        iso_c_binding: ["C_LONG"]

When set to subroutine it will treat the Fortran wrapper as a subroutine. Used when the function result is passed as an argument to the Fortran wrapper instead of being returned as the Fortran wrapper result. Typically to avoid memory allocations by copying directly into the callers variable.

f_module

USE statements to add to Fortran wrapper. A dictionary of list of ONLY names. The names will be expanded before being uses for format values can be used.

If typemap.f_module_name` is None, then the default ``format.f_module_name value will be used. No module will be used in the wrapper in this case. For example, CHARACTER which does not use a kind in the declaration since it uses the Fortran native character kind.

f_module:
  iso_c_binding:
  - C_SIZE_T
  "{f_module_name}":
  - "{f_kind}"

f_temps

A list of suffixes for temporary variable names.

f_temps:
- len

Create variable names in the format dictionary using {fmt.c_temp}{rootname}_{name}. For example, argument foo creates SHT_foo_len.

The format field is named f_var_{name}.

f_local

Similar to f_temps but uses {fmt.C_local}{rootname}_{name}. temps is intended for arguments and is typically used in a mixin group. f_local is used by group to generate names for local variables. This allows creating names without conflicting with f_temps from a mixin group.

The format field is named f_local_{name}.

f_helper

A list of helper function names to add to generated Fortran code. The format dictionary will be applied to the list for additional flexibility.

f_helper:
- array_context

Each helper will add an entry into the format dictionary with the name of the function or type created by the helper defined in the helper’s f_fmtname field. The format value is the helper name prefixed by f_helper_. For example,format field f_helper_array_context may be VEC_SHROUD_array.

See Helpers for a description of helper functions.

f_operator_body

Function code used to overload an operator. An interface block for the operator will also be created.

f_need_wrapper

Shroud tries to only create an interface for a C function to avoid the extra layer of a Fortran wrapper. However, often the Fortran wrapper needs to do some work that the C wrapper cannot. This field can be set to True to ensure the Fortran wrapper is created. This is used when an assignment is needed to do a type coercion; for example, with logical types.

A wrapper will always be created if the F_force_wrapper option is set.

notimplemented

If True the statement is not implemented. The generated function will have #if 0 surrounding the wrapper.

This is a way to avoid generating code which will not compile when the notimplemented wrapper is not needed. For example, the C wrapper for a C++ function when only the C bufferify wrapper is needed for Fortran. The statements should eventually be completed to wrap the function properly.

Fortran Mixins

Shroud provides several mixins that provide some common functionality.

        "name": "f_mixin_declare-fortran-arg",
        "notes": [
            "Fortran wrapper argument."
        ],
        "f_dummy_arg": [
            "{f_var}"
        ],
        "f_dummy_decl": [
            "{f_type}{f_value_attr}{f_intent_attr}{f_deref_attr}{f_target_attr}{f_optional_attr} :: {f_var}{f_dimension}"
        ],
        "f_module": {
            "{f_module_name}": [
                "{f_kind}"
            ]
        },
        "name": "f_mixin_declare-interface-arg",
        "notes": [
            "Declarations for Fortran interface."
        ],
        "i_dummy_arg": [
            "{i_var}"
        ],
        "i_dummy_decl": [
            "{i_type}{f_value_attr}{i_intent_attr} :: {i_var}{i_dimension}"
        ],
        "i_module": {
            "{i_module_name}": [
                "{i_kind}"
            ]
        },