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