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