1c1db35f0Speter klausler //===-- runtime/copy.cpp -------------------------------------------------===//
2c1db35f0Speter klausler //
3c1db35f0Speter klausler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c1db35f0Speter klausler // See https://llvm.org/LICENSE.txt for license information.
5c1db35f0Speter klausler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c1db35f0Speter klausler //
7c1db35f0Speter klausler //===----------------------------------------------------------------------===//
8c1db35f0Speter klausler
9c1db35f0Speter klausler #include "copy.h"
10c1db35f0Speter klausler #include "terminator.h"
11c1db35f0Speter klausler #include "type-info.h"
12*830c0b90SPeter Klausler #include "flang/Runtime/allocatable.h"
13*830c0b90SPeter Klausler #include "flang/Runtime/descriptor.h"
14c1db35f0Speter klausler #include <cstring>
15c1db35f0Speter klausler
16c1db35f0Speter klausler namespace Fortran::runtime {
17c1db35f0Speter klausler
CopyElement(const Descriptor & to,const SubscriptValue toAt[],const Descriptor & from,const SubscriptValue fromAt[],Terminator & terminator)18c1db35f0Speter klausler void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
19c1db35f0Speter klausler const Descriptor &from, const SubscriptValue fromAt[],
20c1db35f0Speter klausler Terminator &terminator) {
21c1db35f0Speter klausler char *toPtr{to.Element<char>(toAt)};
22c1db35f0Speter klausler const char *fromPtr{from.Element<const char>(fromAt)};
23c1db35f0Speter klausler RUNTIME_CHECK(terminator, to.ElementBytes() == from.ElementBytes());
24c1db35f0Speter klausler std::memcpy(toPtr, fromPtr, to.ElementBytes());
25c1db35f0Speter klausler if (const auto *addendum{to.Addendum()}) {
26c1db35f0Speter klausler if (const auto *derived{addendum->derivedType()}) {
27c1db35f0Speter klausler RUNTIME_CHECK(terminator,
28c1db35f0Speter klausler from.Addendum() && derived == from.Addendum()->derivedType());
2979caf69cSpeter klausler const Descriptor &componentDesc{derived->component()};
30c1db35f0Speter klausler const typeInfo::Component *component{
31c1db35f0Speter klausler componentDesc.OffsetElement<typeInfo::Component>()};
32c1db35f0Speter klausler std::size_t nComponents{componentDesc.Elements()};
33c1db35f0Speter klausler for (std::size_t j{0}; j < nComponents; ++j, ++component) {
3479caf69cSpeter klausler if (component->genre() == typeInfo::Component::Genre::Allocatable ||
3579caf69cSpeter klausler component->genre() == typeInfo::Component::Genre::Automatic) {
36c1db35f0Speter klausler Descriptor &toDesc{
3779caf69cSpeter klausler *reinterpret_cast<Descriptor *>(toPtr + component->offset())};
38c1db35f0Speter klausler if (toDesc.raw().base_addr != nullptr) {
39c1db35f0Speter klausler toDesc.set_base_addr(nullptr);
40c1db35f0Speter klausler RUNTIME_CHECK(terminator, toDesc.Allocate() == CFI_SUCCESS);
41c1db35f0Speter klausler const Descriptor &fromDesc{*reinterpret_cast<const Descriptor *>(
4279caf69cSpeter klausler fromPtr + component->offset())};
43c1db35f0Speter klausler CopyArray(toDesc, fromDesc, terminator);
44c1db35f0Speter klausler }
45c1db35f0Speter klausler }
46c1db35f0Speter klausler }
47c1db35f0Speter klausler }
48c1db35f0Speter klausler }
49c1db35f0Speter klausler }
50c1db35f0Speter klausler
CopyArray(const Descriptor & to,const Descriptor & from,Terminator & terminator)51c1db35f0Speter klausler void CopyArray(
52c1db35f0Speter klausler const Descriptor &to, const Descriptor &from, Terminator &terminator) {
53c1db35f0Speter klausler std::size_t elements{to.Elements()};
54c1db35f0Speter klausler RUNTIME_CHECK(terminator, elements == from.Elements());
55c1db35f0Speter klausler SubscriptValue toAt[maxRank], fromAt[maxRank];
56c1db35f0Speter klausler to.GetLowerBounds(toAt);
57c1db35f0Speter klausler from.GetLowerBounds(fromAt);
58c1db35f0Speter klausler while (elements-- > 0) {
59c1db35f0Speter klausler CopyElement(to, toAt, from, fromAt, terminator);
60c1db35f0Speter klausler to.IncrementSubscripts(toAt);
61c1db35f0Speter klausler from.IncrementSubscripts(fromAt);
62c1db35f0Speter klausler }
63c1db35f0Speter klausler }
64c1db35f0Speter klausler } // namespace Fortran::runtime
65