//===-- runtime/inquiry.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 // //===----------------------------------------------------------------------===// // Implements the inquiry intrinsic functions of Fortran 2018 that // inquire about shape information of arrays -- LBOUND and SIZE. #include "flang/Runtime/inquiry.h" #include "copy.h" #include "terminator.h" #include "tools.h" #include "flang/Runtime/descriptor.h" #include namespace Fortran::runtime { template struct RawStoreIntegerAt { RT_API_ATTRS void operator()( void *contiguousIntegerArray, std::size_t at, std::int64_t value) const { reinterpret_cast *>( contiguousIntegerArray)[at] = value; } }; extern "C" { std::int64_t RTDEF(LboundDim)( const Descriptor &array, int dim, const char *sourceFile, int line) { if (dim < 1 || dim > array.rank()) { Terminator terminator{sourceFile, line}; terminator.Crash( "SIZE: bad DIM=%d for ARRAY with rank=%d", dim, array.rank()); } const Dimension &dimension{array.GetDimension(dim - 1)}; return static_cast(dimension.LowerBound()); } void RTDEF(Ubound)(void *result, const Descriptor &array, int kind, const char *sourceFile, int line) { Terminator terminator{sourceFile, line}; INTERNAL_CHECK(array.rank() <= common::maxRank); for (SubscriptValue i{0}; i < array.rank(); ++i) { const Dimension &dimension{array.GetDimension(i)}; Fortran::runtime::ApplyIntegerKind( kind, terminator, result, i, dimension.UpperBound()); } } std::int64_t RTDEF(Size)( const Descriptor &array, const char *sourceFile, int line) { std::int64_t result{1}; for (int i = 0; i < array.rank(); ++i) { const Dimension &dimension{array.GetDimension(i)}; result *= dimension.Extent(); } return result; } std::int64_t RTDEF(SizeDim)( const Descriptor &array, int dim, const char *sourceFile, int line) { if (dim < 1 || dim > array.rank()) { Terminator terminator{sourceFile, line}; terminator.Crash( "SIZE: bad DIM=%d for ARRAY with rank=%d", dim, array.rank()); } const Dimension &dimension{array.GetDimension(dim - 1)}; return static_cast(dimension.Extent()); } void RTDEF(Shape)(void *result, const Descriptor &array, int kind, const char *sourceFile, int line) { Terminator terminator{sourceFile, line}; INTERNAL_CHECK(array.rank() <= common::maxRank); for (SubscriptValue i{0}; i < array.rank(); ++i) { const Dimension &dimension{array.GetDimension(i)}; Fortran::runtime::ApplyIntegerKind( kind, terminator, result, i, dimension.Extent()); } } void RTDEF(Lbound)(void *result, const Descriptor &array, int kind, const char *sourceFile, int line) { Terminator terminator{sourceFile, line}; INTERNAL_CHECK(array.rank() <= common::maxRank); for (SubscriptValue i{0}; i < array.rank(); ++i) { const Dimension &dimension{array.GetDimension(i)}; Fortran::runtime::ApplyIntegerKind( kind, terminator, result, i, dimension.LowerBound()); } } } // extern "C" } // namespace Fortran::runtime