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