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

source code of flang/runtime/copy.cpp