FLANG
allocatable.h
1//===-- include/flang/Runtime/allocatable.h ---------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// Defines APIs for Fortran runtime library support of code generated
10// to manipulate and query allocatable variables, dummy arguments, & components.
11#ifndef FORTRAN_RUNTIME_ALLOCATABLE_H_
12#define FORTRAN_RUNTIME_ALLOCATABLE_H_
13
14#include "flang/Runtime/descriptor-consts.h"
15#include "flang/Runtime/entry-names.h"
16#include "flang/Runtime/freestanding-tools.h"
17
18namespace Fortran::runtime {
19
20extern "C" {
21
22// Initializes the descriptor for an allocatable of intrinsic or derived type.
23// The incoming descriptor is treated as (and can be) uninitialized garbage.
24// Must be called for each allocatable variable as its scope comes into being.
25// The storage for the allocatable's descriptor must have already been
26// allocated to a size sufficient for the rank, corank, and type.
27// A descriptor must be initialized before being used for any purpose,
28// but needs reinitialization in a deallocated state only when there is
29// a change of type, rank, or corank.
30void RTDECL(AllocatableInitIntrinsic)(
31 Descriptor &, TypeCategory, int kind, int rank = 0, int corank = 0);
32void RTDECL(AllocatableInitCharacter)(Descriptor &, SubscriptValue length = 0,
33 int kind = 1, int rank = 0, int corank = 0);
34void RTDECL(AllocatableInitDerived)(
35 Descriptor &, const typeInfo::DerivedType &, int rank = 0, int corank = 0);
36
37// Initializes the descriptor for an allocatable of intrinsic or derived type.
38// These functions are meant to be used in the allocate statement lowering. If
39// the descriptor is allocated, the initialization is skiped so the error
40// handling can be done by AllocatableAllocate.
41void RTDECL(AllocatableInitIntrinsicForAllocate)(
42 Descriptor &, TypeCategory, int kind, int rank = 0, int corank = 0);
43void RTDECL(AllocatableInitCharacterForAllocate)(Descriptor &,
44 SubscriptValue length = 0, int kind = 1, int rank = 0, int corank = 0);
45void RTDECL(AllocatableInitDerivedForAllocate)(
46 Descriptor &, const typeInfo::DerivedType &, int rank = 0, int corank = 0);
47
48// Checks that an allocatable is not already allocated in statements
49// with STAT=. Use this on a value descriptor before setting bounds or
50// type parameters. Not necessary on a freshly initialized descriptor.
51// (If there's no STAT=, the error will be caught later anyway, but
52// this API allows the error to be caught before descriptor is modified.)
53// Return 0 on success (deallocated state), else the STAT= value.
54int RTDECL(AllocatableCheckAllocated)(Descriptor &,
55 const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
56 int sourceLine = 0);
57
58// For MOLD= allocation; sets bounds, cobounds, and length type
59// parameters from another descriptor. The destination descriptor must
60// be initialized and deallocated.
61void RTDECL(AllocatableApplyMold)(
62 Descriptor &, const Descriptor &mold, int rank = 0);
63
64// Explicitly sets the bounds and length type parameters of an initialized
65// deallocated allocatable.
66void RTDECL(AllocatableSetBounds)(
67 Descriptor &, int zeroBasedDim, SubscriptValue lower, SubscriptValue upper);
68
69// The upper cobound is ignored for the last codimension.
70void RTDECL(AllocatableSetCoBounds)(Descriptor &, int zeroBasedCoDim,
71 SubscriptValue lower, SubscriptValue upper = 0);
72
73// Length type parameters are indexed in declaration order; i.e., 0 is the
74// first length type parameter in the deepest base type. (Not for use
75// with CHARACTER; see above.)
76void RTDECL(AllocatableSetDerivedLength)(
77 Descriptor &, int which, SubscriptValue);
78
79// When an explicit type-spec appears in an ALLOCATE statement for an
80// allocatable with an explicit (non-deferred) length type paramater for
81// a derived type or CHARACTER value, the explicit value has to match
82// the length type parameter's value. This API checks that requirement.
83// Returns 0 for success, or the STAT= value on failure with hasStat==true.
84int RTDECL(AllocatableCheckLengthParameter)(Descriptor &,
85 int which /* 0 for CHARACTER length */, SubscriptValue other,
86 bool hasStat = false, const Descriptor *errMsg = nullptr,
87 const char *sourceFile = nullptr, int sourceLine = 0);
88
89// Allocates an allocatable. The allocatable descriptor must have been
90// initialized and its bounds and length type parameters set and must be
91// in a deallocated state.
92// On failure, if hasStat is true, returns a nonzero error code for
93// STAT= and (if present) fills in errMsg; if hasStat is false, the
94// image is terminated. On success, leaves errMsg alone and returns zero.
95// Successfully allocated memory is initialized if the allocatable has a
96// derived type, and is always initialized by AllocatableAllocateSource().
97// Performs all necessary coarray synchronization and validation actions.
98#ifdef RT_DEVICE_COMPILATION
99int RTDECL(AllocatableAllocate)(Descriptor &,
100 std::int64_t *asyncObject = nullptr, bool hasStat = false,
101 const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
102 int sourceLine = 0, MemcpyFct memcpyFct = &MemcpyWrapper);
103#else
104int RTDECL(AllocatableAllocate)(Descriptor &,
105 std::int64_t *asyncObject = nullptr, bool hasStat = false,
106 const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
107 int sourceLine = 0, MemcpyFct memcpyFct = &Fortran::runtime::memcpy);
108#endif
109int RTDECL(AllocatableAllocateSource)(Descriptor &, const Descriptor &source,
110 bool hasStat = false, const Descriptor *errMsg = nullptr,
111 const char *sourceFile = nullptr, int sourceLine = 0);
112
113// Implements the intrinsic subroutine MOVE_ALLOC (16.9.137 in F'2018,
114// but note the order of first two arguments is reversed for consistency
115// with the other APIs for allocatables.) The destination descriptor
116// must be initialized.
117std::int32_t RTDECL(MoveAlloc)(Descriptor &to, Descriptor &from,
118 const typeInfo::DerivedType *, bool hasStat = false,
119 const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
120 int sourceLine = 0);
121
122// Deallocates an allocatable. Finalizes elements &/or components as needed.
123// The allocatable is left in an initialized state suitable for reallocation
124// with the same bounds, cobounds, and length type parameters.
125int RTDECL(AllocatableDeallocate)(Descriptor &, bool hasStat = false,
126 const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
127 int sourceLine = 0);
128
129// Same as AllocatableDeallocate but also set the dynamic type as the declared
130// type as mentioned in 7.3.2.3 note 7.
131int RTDECL(AllocatableDeallocatePolymorphic)(Descriptor &,
132 const typeInfo::DerivedType *, bool hasStat = false,
133 const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr,
134 int sourceLine = 0);
135
136// Variant of above that does not finalize; for intermediate results
137void RTDECL(AllocatableDeallocateNoFinal)(
138 Descriptor &, const char *sourceFile = nullptr, int sourceLine = 0);
139} // extern "C"
140} // namespace Fortran::runtime
141#endif // FORTRAN_RUNTIME_ALLOCATABLE_H_