2020-03-31 07:37:30 +08:00
|
|
|
//===-- runtime/allocatable.cpp ---------------------------------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// 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 "allocatable.h"
|
2020-11-11 07:13:02 +08:00
|
|
|
#include "stat.h"
|
2020-03-31 07:37:30 +08:00
|
|
|
#include "terminator.h"
|
|
|
|
|
|
|
|
namespace Fortran::runtime {
|
|
|
|
extern "C" {
|
|
|
|
|
2020-11-11 07:13:02 +08:00
|
|
|
void RTNAME(AllocatableInitIntrinsic)(Descriptor &descriptor,
|
|
|
|
TypeCategory category, int kind, int rank, int corank) {
|
|
|
|
INTERNAL_CHECK(corank == 0);
|
|
|
|
descriptor.Establish(TypeCode{category, kind},
|
|
|
|
Descriptor::BytesFor(category, kind), nullptr, rank, nullptr,
|
|
|
|
CFI_attribute_allocatable);
|
2020-03-31 07:37:30 +08:00
|
|
|
}
|
|
|
|
|
2020-11-11 07:13:02 +08:00
|
|
|
void RTNAME(AllocatableInitCharacter)(Descriptor &descriptor,
|
|
|
|
SubscriptValue length, int kind, int rank, int corank) {
|
|
|
|
INTERNAL_CHECK(corank == 0);
|
|
|
|
descriptor.Establish(
|
|
|
|
kind, length, nullptr, rank, nullptr, CFI_attribute_allocatable);
|
2020-03-31 07:37:30 +08:00
|
|
|
}
|
|
|
|
|
2020-11-11 07:13:02 +08:00
|
|
|
void RTNAME(AllocatableInitDerived)(Descriptor &descriptor,
|
|
|
|
const DerivedType &derivedType, int rank, int corank) {
|
|
|
|
INTERNAL_CHECK(corank == 0);
|
|
|
|
descriptor.Establish(
|
|
|
|
derivedType, nullptr, rank, nullptr, CFI_attribute_allocatable);
|
2020-03-31 07:37:30 +08:00
|
|
|
}
|
|
|
|
|
2020-11-11 07:13:02 +08:00
|
|
|
void RTNAME(AllocatableAssign)(Descriptor &to, const Descriptor & /*from*/) {
|
|
|
|
INTERNAL_CHECK(!"AllocatableAssign is not yet implemented");
|
|
|
|
}
|
2020-03-31 07:37:30 +08:00
|
|
|
|
|
|
|
int RTNAME(MoveAlloc)(Descriptor &to, const Descriptor & /*from*/,
|
|
|
|
bool /*hasStat*/, Descriptor * /*errMsg*/, const char * /*sourceFile*/,
|
|
|
|
int /*sourceLine*/) {
|
2020-11-11 07:13:02 +08:00
|
|
|
INTERNAL_CHECK(!"MoveAlloc is not yet implemented");
|
|
|
|
return StatOk;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RTNAME(AllocatableSetBounds)(Descriptor &descriptor, int zeroBasedDim,
|
|
|
|
SubscriptValue lower, SubscriptValue upper) {
|
|
|
|
INTERNAL_CHECK(zeroBasedDim >= 0 && zeroBasedDim < descriptor.rank());
|
|
|
|
descriptor.GetDimension(zeroBasedDim).SetBounds(lower, upper);
|
|
|
|
// The byte strides are computed when the object is allocated.
|
|
|
|
}
|
|
|
|
|
|
|
|
int RTNAME(AllocatableAllocate)(Descriptor &descriptor, bool hasStat,
|
|
|
|
Descriptor *errMsg, const char *sourceFile, int sourceLine) {
|
|
|
|
Terminator terminator{sourceFile, sourceLine};
|
|
|
|
if (!descriptor.IsAllocatable()) {
|
|
|
|
return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat);
|
|
|
|
}
|
|
|
|
if (descriptor.IsAllocated()) {
|
|
|
|
return ReturnError(terminator, StatBaseNotNull, errMsg, hasStat);
|
|
|
|
}
|
|
|
|
return ReturnError(terminator, descriptor.Allocate(), errMsg, hasStat);
|
2020-03-31 07:37:30 +08:00
|
|
|
}
|
|
|
|
|
2020-11-11 07:13:02 +08:00
|
|
|
int RTNAME(AllocatableDeallocate)(Descriptor &descriptor, bool hasStat,
|
|
|
|
Descriptor *errMsg, const char *sourceFile, int sourceLine) {
|
|
|
|
Terminator terminator{sourceFile, sourceLine};
|
|
|
|
if (!descriptor.IsAllocatable()) {
|
|
|
|
return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat);
|
|
|
|
}
|
|
|
|
if (!descriptor.IsAllocated()) {
|
|
|
|
return ReturnError(terminator, StatBaseNull, errMsg, hasStat);
|
|
|
|
}
|
|
|
|
return ReturnError(terminator, descriptor.Deallocate(), errMsg, hasStat);
|
2020-03-31 07:37:30 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace Fortran::runtime
|