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