|
21 | 21 | #include "flang-rt/runtime/descriptor.h" |
22 | 22 | #include "flang-rt/runtime/terminator.h" |
23 | 23 | #include "flang-rt/runtime/tools.h" |
| 24 | +#include "flang-rt/runtime/type-info.h" |
24 | 25 | #include "flang/Common/float128.h" |
25 | 26 |
|
26 | 27 | namespace Fortran::runtime { |
@@ -323,6 +324,71 @@ static inline RT_API_ATTRS void DoBesselYnX0(Descriptor &result, int32_t n1, |
323 | 324 | } |
324 | 325 | } |
325 | 326 |
|
| 327 | +static inline RT_API_ATTRS void CheckConformabilityForShallowCopy( |
| 328 | + const Descriptor &d1, const Descriptor &d2, Terminator &terminator, |
| 329 | + const char *funcName, const char *d1Name, const char *d2Name) { |
| 330 | + if (d1.rank() != d2.rank()) { |
| 331 | + terminator.Crash( |
| 332 | + "Incompatible arguments to %s: %s has rank %d, %s has rank %d", |
| 333 | + funcName, d1Name, d1.rank(), d1Name, d2.rank()); |
| 334 | + } |
| 335 | + |
| 336 | + // Check that the shapes conform. |
| 337 | + CheckConformability(d1, d2, terminator, funcName, d1Name, d2Name); |
| 338 | + |
| 339 | + if (d1.ElementBytes() != d2.ElementBytes()) { |
| 340 | + terminator.Crash("Incompatible arguments to %s: %s has element byte length " |
| 341 | + "%zd, %s has length %zd", |
| 342 | + funcName, d1Name, d1.ElementBytes(), d2Name, d2.ElementBytes()); |
| 343 | + } |
| 344 | + if (d1.type() != d2.type()) { |
| 345 | + terminator.Crash("Incompatible arguments to %s: %s has type code %d, %s " |
| 346 | + "has type code %d", |
| 347 | + funcName, d1Name, d1.type(), d2Name, d2.type()); |
| 348 | + } |
| 349 | + const DescriptorAddendum *d1Addendum{d1.Addendum()}; |
| 350 | + const typeInfo::DerivedType *d1Derived{ |
| 351 | + d1Addendum ? d1Addendum->derivedType() : nullptr}; |
| 352 | + const DescriptorAddendum *d2Addendum{d2.Addendum()}; |
| 353 | + const typeInfo::DerivedType *d2Derived{ |
| 354 | + d2Addendum ? d2Addendum->derivedType() : nullptr}; |
| 355 | + if (d1Derived != d2Derived) { |
| 356 | + terminator.Crash( |
| 357 | + "Incompatible arguments to %s: %s and %s have different derived types", |
| 358 | + funcName, d1Name, d2Name); |
| 359 | + } |
| 360 | + if (d2Derived) { |
| 361 | + // Compare LEN parameters. |
| 362 | + std::size_t lenParms{d2Derived->LenParameters()}; |
| 363 | + for (std::size_t j{0}; j < lenParms; ++j) { |
| 364 | + if (d1Addendum->LenParameterValue(j) != |
| 365 | + d2Addendum->LenParameterValue(j)) { |
| 366 | + terminator.Crash("Incompatible arguments to %s: type length parameter " |
| 367 | + "%zd for %s is %zd, for %s is %zd", |
| 368 | + funcName, j, d1Name, |
| 369 | + static_cast<std::size_t>(d1Addendum->LenParameterValue(j)), d2Name, |
| 370 | + static_cast<std::size_t>(d2Addendum->LenParameterValue(j))); |
| 371 | + } |
| 372 | + } |
| 373 | + } |
| 374 | +} |
| 375 | + |
| 376 | +template <bool IS_ALLOCATING> |
| 377 | +static inline RT_API_ATTRS void DoShallowCopy( |
| 378 | + std::conditional_t<IS_ALLOCATING, Descriptor, const Descriptor> &result, |
| 379 | + const Descriptor &source, Terminator &terminator, const char *funcName) { |
| 380 | + if constexpr (IS_ALLOCATING) { |
| 381 | + SubscriptValue extent[maxRank]; |
| 382 | + source.GetShape(extent); |
| 383 | + AllocateResult(result, source, source.rank(), extent, terminator, funcName); |
| 384 | + } else { |
| 385 | + CheckConformabilityForShallowCopy( |
| 386 | + result, source, terminator, funcName, "RESULT=", "SOURCE="); |
| 387 | + } |
| 388 | + |
| 389 | + ShallowCopy(result, source); |
| 390 | +} |
| 391 | + |
326 | 392 | extern "C" { |
327 | 393 | RT_EXT_API_GROUP_BEGIN |
328 | 394 |
|
@@ -815,6 +881,19 @@ void RTDEF(Reshape)(Descriptor &result, const Descriptor &source, |
815 | 881 | } |
816 | 882 | } |
817 | 883 |
|
| 884 | +// ShallowCopy |
| 885 | +void RTDEF(ShallowCopy)(Descriptor &result, const Descriptor &source, |
| 886 | + const char *sourceFile, int line) { |
| 887 | + Terminator terminator{sourceFile, line}; |
| 888 | + DoShallowCopy<true>(result, source, terminator, "ShallowCopy"); |
| 889 | +} |
| 890 | + |
| 891 | +void RTDEF(ShallowCopyDirect)(const Descriptor &result, |
| 892 | + const Descriptor &source, const char *sourceFile, int line) { |
| 893 | + Terminator terminator{sourceFile, line}; |
| 894 | + DoShallowCopy<false>(result, source, terminator, "ShallowCopyDirect"); |
| 895 | +} |
| 896 | + |
818 | 897 | // SPREAD |
819 | 898 | void RTDEF(Spread)(Descriptor &result, const Descriptor &source, int dim, |
820 | 899 | std::int64_t ncopies, const char *sourceFile, int line) { |
|
0 commit comments