Warning: This file is not a C or C++ file. It does not have highlighting.
1 | //===-- include/flang/Runtime/array-constructor.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 | // External APIs to create temporary storage for array constructors when their |
10 | // final extents or length parameters cannot be pre-computed. |
11 | |
12 | #ifndef FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_ |
13 | #define FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_ |
14 | |
15 | #include "flang/Runtime/descriptor.h" |
16 | #include "flang/Runtime/entry-names.h" |
17 | #include <cstdint> |
18 | |
19 | namespace Fortran::runtime { |
20 | |
21 | // Runtime data structure to hold information about the storage of |
22 | // an array constructor being constructed. |
23 | struct ArrayConstructorVector { |
24 | RT_API_ATTRS ArrayConstructorVector(class Descriptor &to, |
25 | SubscriptValue nextValuePosition, SubscriptValue actualAllocationSize, |
26 | const char *sourceFile, int sourceLine, bool useValueLengthParameters) |
27 | : to{to}, nextValuePosition{nextValuePosition}, |
28 | actualAllocationSize{actualAllocationSize}, sourceFile{sourceFile}, |
29 | sourceLine{sourceLine}, |
30 | useValueLengthParameters_{useValueLengthParameters} {} |
31 | |
32 | RT_API_ATTRS bool useValueLengthParameters() const { |
33 | return useValueLengthParameters_; |
34 | } |
35 | |
36 | class Descriptor &to; |
37 | SubscriptValue nextValuePosition; |
38 | SubscriptValue actualAllocationSize; |
39 | const char *sourceFile; |
40 | int sourceLine; |
41 | |
42 | private: |
43 | unsigned char useValueLengthParameters_ : 1; |
44 | }; |
45 | |
46 | // This file defines an API to "push" an evaluated array constructor value |
47 | // "from" into some storage "to" of an array constructor. It can be seen as a |
48 | // form of std::vector::push_back() implementation for Fortran array |
49 | // constructors. In the APIs and ArrayConstructorVector struct above: |
50 | // |
51 | // - "to" is a ranked-1 descriptor whose declared type is already set to the |
52 | // array constructor derived type. It may be already allocated, even before the |
53 | // first call to this API, or it may be unallocated. "to" extent is increased |
54 | // every time a "from" is pushed past its current extent. At this end of the |
55 | // API calls, its extent is the extent of the array constructor. If "to" is |
56 | // unallocated and its extent is not null, it is assumed this is the final array |
57 | // constructor extent value, and the first allocation already "reserves" storage |
58 | // space accordingly to avoid reallocations. |
59 | // - "from" is a scalar or array descriptor for the evaluated array |
60 | // constructor value that must be copied into the storage of "to" at |
61 | // "nextValuePosition". |
62 | // - "useValueLengthParameters" must be set to true if the array constructor |
63 | // has length parameters and no type spec. If it is true and "to" is |
64 | // unallocated, "to" will take the length parameters of "from". If it is true |
65 | // and "to" is an allocated character array constructor, it will be checked |
66 | // that "from" length matches the one from "to". When it is false, the |
67 | // character length must already be set in "to" before the first call to this |
68 | // API and "from" character lengths are allowed to mismatch from "to". |
69 | // - "nextValuePosition" is the zero based sequence position of "from" in the |
70 | // array constructor. It is updated after this call by the number of "from" |
71 | // elements. It should be set to zero by the caller of this API before the first |
72 | // call. |
73 | // - "actualAllocationSize" is the current allocation size of "to" storage. It |
74 | // may be bigger than "to" extent for reallocation optimization purposes, but |
75 | // should never be smaller, unless this is the first call and "to" is |
76 | // unallocated. It is updated by the runtime after each successful allocation or |
77 | // reallocation. It should be set to "to" extent if "to" is allocated before the |
78 | // first call of this API, and can be left undefined otherwise. |
79 | // |
80 | // Note that this API can be used with "to" being a variable (that can be |
81 | // discontiguous). This can be done when the variable is the left hand side of |
82 | // an assignment from an array constructor as long as: |
83 | // - none of the ac-value overlaps with the variable, |
84 | // - this is an intrinsic assignment that is not a whole allocatable |
85 | // assignment, *and* for a type that has no components requiring user defined |
86 | // assignments, |
87 | // - the variable is properly finalized before using this API if its need to, |
88 | // - "useValueLengthParameters" should be set to false in this case, even if |
89 | // the array constructor has no type-spec, since the variable may have a |
90 | // different character length than the array constructor values. |
91 | |
92 | extern "C" { |
93 | // API to initialize an ArrayConstructorVector before any values are pushed to |
94 | // it. Inlined code is only expected to allocate the "ArrayConstructorVector" |
95 | // class instance storage with sufficient size (using |
96 | // "2*sizeof(ArrayConstructorVector)" on the host should be safe regardless of |
97 | // the target the runtime is compiled for). This avoids the need for the runtime |
98 | // to maintain a state, or to use dynamic allocation for it. "vectorClassSize" |
99 | // is used to validate that lowering allocated enough space for it. |
100 | void RTDECL(InitArrayConstructorVector)(ArrayConstructorVector &vector, |
101 | Descriptor &to, bool useValueLengthParameters, int vectorClassSize, |
102 | const char *sourceFile = nullptr, int sourceLine = 0); |
103 | |
104 | // Generic API to push any kind of entity into the array constructor (any |
105 | // Fortran type and any rank). |
106 | void RTDECL(PushArrayConstructorValue)( |
107 | ArrayConstructorVector &vector, const Descriptor &from); |
108 | |
109 | // API to push scalar array constructor value of: |
110 | // - a numerical or logical type, |
111 | // - or a derived type that has no length parameters, and no allocatable |
112 | // component (that would require deep copies). |
113 | // It requires no descriptor for the value that is passed via its base address. |
114 | void RTDECL(PushArrayConstructorSimpleScalar)( |
115 | ArrayConstructorVector &vector, void *from); |
116 | } // extern "C" |
117 | } // namespace Fortran::runtime |
118 | #endif // FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_ |
119 |
Warning: This file is not a C or C++ file. It does not have highlighting.