# loki.transformations.transform_derived_types module

Transformations dealing with derived types in subroutines and derived-type arguments in complex calling structures.

> - DerivedTypeArgumentsTransformation:

>     Transformation to resolve array-of-structure (AOS) uses of derived-type variables to explicitly expose arrays from which to hoist dimensions.

class DerivedTypeArgumentsTransformation(all_derived_types=False, key=None, **kwargs)

  Bases: `Transformation`

  Remove derived types from procedure signatures by replacing the (relevant) derived type arguments by its member variables

  Note

  This transformation requires a Scheduler traversal that processes callees before callers.

  On the caller side, this updates calls to transformed subroutines and functions by passing the relevant derived type member variables instead of the original derived type argument. This uses information from previous application of this transformation to the called procedure.

  On the callee side, this identifies derived type member variable usage, builds an expansion mapping, updates the procedure’s signature accordingly, and substitutes the variable’s use inside the routine. The information about the expansion map is stored in the `Item`’s `trafo_data`. See `expand_derived_args_kernel()` for more information.

  Parameters:

    - all_derived_types (bool, optional) – Whether to remove all derived types from procedure signatures by replacing the derived type arguments using its member variables or only the “relevant” ones, referring to derived types with array members or nested derived types (default: False).

    - key (str, optional) – Overwrite the key that is used to store analysis results in `trafo_data`.

  reverse_traversal = True

    Traversal from the leaves upwards

  transform_subroutine(routine, **kwargs)

    Defines the transformation to apply to `Subroutine` items.

    For transformations that modify `Subroutine` objects, this method should be implemented. It gets called via the dispatch method `apply()`.

    Parameters:

      - routine (`Subroutine`) – The subroutine to be transformed.

      - **kwargs (optional) – Keyword arguments for the transformation.

  expand_derived_args_caller(routine, successors_data)

    For all active `CallStatement` nodes, apply the derived type argument expansion on the caller side.

    The convention used is: `derived%var => derived_var`.

    Parameters:

      - routine (`Subroutine`) – The routine in which to transform call statements

      - successors_data (`CaseInsensitiveDict` of (str, dict)) – Dictionary containing the expansion maps (key `'expansion_map'`) and original argnames (key `'orig_argnames'`) of every child routine

    Returns:

      Flag to indicate that dependencies have been changed (e.g. via new imports)

    Return type:

      bool

  classmethod expand_call_arguments(call, successor_data)

    Create the call’s argument list with derived type arguments expanded

    Parameters:

      - call (`CallStatement`) – The call statement to process

      - successor_data (dict) – Dictionary containing the expansion map (key `'expansion_map'`) and original argnames (key `'orig_argnames'`) of the called routine

    Returns:

      The argument and keyword argument list with derived type arguments expanded

    Return type:

      (tuple, tuple)

  expand_derived_args_kernel(routine)

    Find the use of member variables for derived type arguments of `routine`, update the call signature to directly pass the variable and substitute its use in the routine’s body.

    Note that this will only carry out replacements for derived types that contain an allocatable, pointer, or nested derived type member.

    See `expand_derived_type_member()` for more details on how the expansion is performed.

  classmethod expand_derived_type_member(var)

    Determine the member expansion for a derived type member variable

    For a derived type member variable, provided as `var`, this determines the name of the root parent and the member expansion.

    A few examples to illustrate the behaviour, with the Fortran variable use that `var` represents in the left column and corresponding return value of this routine on the right:

         var name            | return value (parent_name, expansion, new use)   | remarks
        ---------------------+--------------------------------------------------+------------------------------------
         SOME_VAR            | ('some_var', None, None)                         | No expansion
         SOME%VAR            | ('some', 'some%var', 'some_var')                 |
         ARRAY(5)%VAR        | ('array', None, None)                            | Can't expand array of derived types
         SOME%NESTED%VAR     | ('some', 'some%nested%var', 'some_nested_var)    |
         NESTED%ARRAY(I)%VAR | ('nested', 'nested%array', 'nested_array(i)%var')| Partial expansion

    Parameters:

      var (`MetaSymbol`) – The use of a derived type member

    Return type:

      (`Variable`, `Variable` or None, `Variable` or None)

  classmethod add_new_imports_kernel(routine, trafo_data)

    Inspect the expansion map in `trafo_data` for new symbols that need to be imported as a result of flattening a derived type and add the corresponding imports

  classmethod expand_derived_args_recursion(routine, trafo_data)

    Find recursive calls to itcls and apply the derived args flattening to these calls

class TypeboundProcedureCallTransformation(duplicate_typebound_kernels=False, fix_intent=True, **kwargs)

  Bases: `Transformation`

  Replace calls to type-bound procedures with direct calls to the corresponding subroutines/functions

  Instead of calling a type-bound procedure, e.g. `CALL my_type%proc`, it is possible to import the bound procedure and call it directly, with the derived type as first argument, i.e. `CALL proc(my_type)`. This transformation replaces all calls to type-bound procedures accordingly and inserts necessary imports.

  Also, for some compilers these direct calls seem to require an explicit `INTENT` specification on the polymorphic derived type dummy argument, which is set to INOUT by default, if missing. This behaviour can be switched off by setting `fix_intent` to False.

  Parameters:

    - duplicate_typebound_kernels (bool) – Optionally, create a copy of unchanged routines before flattening calls to typebound procedures, and update the procedure binding to point to the unchanged copy.

    - fix_intent (bool) – Update intent on polymorphic dummy arguments missing an intent as `INOUT`.

  apply_default_polymorphic_intent(routine)

    Utility routine to set a default `INTENT(INOUT)` on polymorphic dummy arguments (i.e. declared via `CLASS`) that don’t have an explicit intent

  transform_subroutine(routine, **kwargs)

    Apply the transformation of calls to the given `routine`