forked from OSchip/llvm-project
65 lines
2.5 KiB
C++
65 lines
2.5 KiB
C++
//===-- runtime/copy.cpp -------------------------------------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "copy.h"
|
|
#include "terminator.h"
|
|
#include "type-info.h"
|
|
#include "flang/Runtime/allocatable.h"
|
|
#include "flang/Runtime/descriptor.h"
|
|
#include <cstring>
|
|
|
|
namespace Fortran::runtime {
|
|
|
|
void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
|
|
const Descriptor &from, const SubscriptValue fromAt[],
|
|
Terminator &terminator) {
|
|
char *toPtr{to.Element<char>(toAt)};
|
|
const char *fromPtr{from.Element<const char>(fromAt)};
|
|
RUNTIME_CHECK(terminator, to.ElementBytes() == from.ElementBytes());
|
|
std::memcpy(toPtr, fromPtr, to.ElementBytes());
|
|
if (const auto *addendum{to.Addendum()}) {
|
|
if (const auto *derived{addendum->derivedType()}) {
|
|
RUNTIME_CHECK(terminator,
|
|
from.Addendum() && derived == from.Addendum()->derivedType());
|
|
const Descriptor &componentDesc{derived->component()};
|
|
const typeInfo::Component *component{
|
|
componentDesc.OffsetElement<typeInfo::Component>()};
|
|
std::size_t nComponents{componentDesc.Elements()};
|
|
for (std::size_t j{0}; j < nComponents; ++j, ++component) {
|
|
if (component->genre() == typeInfo::Component::Genre::Allocatable ||
|
|
component->genre() == typeInfo::Component::Genre::Automatic) {
|
|
Descriptor &toDesc{
|
|
*reinterpret_cast<Descriptor *>(toPtr + component->offset())};
|
|
if (toDesc.raw().base_addr != nullptr) {
|
|
toDesc.set_base_addr(nullptr);
|
|
RUNTIME_CHECK(terminator, toDesc.Allocate() == CFI_SUCCESS);
|
|
const Descriptor &fromDesc{*reinterpret_cast<const Descriptor *>(
|
|
fromPtr + component->offset())};
|
|
CopyArray(toDesc, fromDesc, terminator);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CopyArray(
|
|
const Descriptor &to, const Descriptor &from, Terminator &terminator) {
|
|
std::size_t elements{to.Elements()};
|
|
RUNTIME_CHECK(terminator, elements == from.Elements());
|
|
SubscriptValue toAt[maxRank], fromAt[maxRank];
|
|
to.GetLowerBounds(toAt);
|
|
from.GetLowerBounds(fromAt);
|
|
while (elements-- > 0) {
|
|
CopyElement(to, toAt, from, fromAt, terminator);
|
|
to.IncrementSubscripts(toAt);
|
|
from.IncrementSubscripts(fromAt);
|
|
}
|
|
}
|
|
} // namespace Fortran::runtime
|