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