1 //===-- runtime/copy.cpp -------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include "terminator.h"
11 #include "type-info.h"
12 #include "flang/Runtime/allocatable.h"
13 #include "flang/Runtime/descriptor.h"
16 namespace Fortran::runtime
{
18 void CopyElement(const Descriptor
&to
, const SubscriptValue toAt
[],
19 const Descriptor
&from
, const SubscriptValue fromAt
[],
20 Terminator
&terminator
) {
21 char *toPtr
{to
.Element
<char>(toAt
)};
22 const char *fromPtr
{from
.Element
<const char>(fromAt
)};
23 RUNTIME_CHECK(terminator
, to
.ElementBytes() == from
.ElementBytes());
24 std::memcpy(toPtr
, fromPtr
, to
.ElementBytes());
25 if (const auto *addendum
{to
.Addendum()}) {
26 if (const auto *derived
{addendum
->derivedType()}) {
27 RUNTIME_CHECK(terminator
,
28 from
.Addendum() && derived
== from
.Addendum()->derivedType());
29 const Descriptor
&componentDesc
{derived
->component()};
30 const typeInfo::Component
*component
{
31 componentDesc
.OffsetElement
<typeInfo::Component
>()};
32 std::size_t nComponents
{componentDesc
.Elements()};
33 for (std::size_t j
{0}; j
< nComponents
; ++j
, ++component
) {
34 if (component
->genre() == typeInfo::Component::Genre::Allocatable
||
35 component
->genre() == typeInfo::Component::Genre::Automatic
) {
37 *reinterpret_cast<Descriptor
*>(toPtr
+ component
->offset())};
38 if (toDesc
.raw().base_addr
!= nullptr) {
39 toDesc
.set_base_addr(nullptr);
40 RUNTIME_CHECK(terminator
, toDesc
.Allocate() == CFI_SUCCESS
);
41 const Descriptor
&fromDesc
{*reinterpret_cast<const Descriptor
*>(
42 fromPtr
+ component
->offset())};
43 CopyArray(toDesc
, fromDesc
, terminator
);
52 const Descriptor
&to
, const Descriptor
&from
, Terminator
&terminator
) {
53 std::size_t elements
{to
.Elements()};
54 RUNTIME_CHECK(terminator
, elements
== from
.Elements());
55 SubscriptValue toAt
[maxRank
], fromAt
[maxRank
];
56 to
.GetLowerBounds(toAt
);
57 from
.GetLowerBounds(fromAt
);
58 while (elements
-- > 0) {
59 CopyElement(to
, toAt
, from
, fromAt
, terminator
);
60 to
.IncrementSubscripts(toAt
);
61 from
.IncrementSubscripts(fromAt
);
64 } // namespace Fortran::runtime