@@ -17,6 +17,19 @@ namespace Fortran::runtime {
17
17
18
18
RT_OFFLOAD_API_GROUP_BEGIN
19
19
20
+ // Fill "extents" array with the extents of component "comp" from derived type
21
+ // instance "derivedInstance".
22
+ static RT_API_ATTRS void GetComponentExtents (SubscriptValue (&extents)[maxRank],
23
+ const typeInfo::Component &comp, const Descriptor &derivedInstance) {
24
+ const typeInfo::Value *bounds{comp.bounds ()};
25
+ for (int dim{0 }; dim < comp.rank (); ++dim) {
26
+ SubscriptValue lb{bounds[2 * dim].GetValue (&derivedInstance).value_or (0 )};
27
+ SubscriptValue ub{
28
+ bounds[2 * dim + 1 ].GetValue (&derivedInstance).value_or (0 )};
29
+ extents[dim] = ub >= lb ? ub - lb + 1 : 0 ;
30
+ }
31
+ }
32
+
20
33
RT_API_ATTRS int Initialize (const Descriptor &instance,
21
34
const typeInfo::DerivedType &derived, Terminator &terminator, bool hasStat,
22
35
const Descriptor *errMsg) {
@@ -77,22 +90,15 @@ RT_API_ATTRS int Initialize(const Descriptor &instance,
77
90
comp.derivedType () && !comp.derivedType ()->noInitializationNeeded ()) {
78
91
// Default initialization of non-pointer non-allocatable/automatic
79
92
// data component. Handles parent component's elements. Recursive.
80
- SubscriptValue extent[maxRank];
81
- const typeInfo::Value *bounds{comp.bounds ()};
82
- for (int dim{0 }; dim < comp.rank (); ++dim) {
83
- typeInfo::TypeParameterValue lb{
84
- bounds[2 * dim].GetValue (&instance).value_or (0 )};
85
- typeInfo::TypeParameterValue ub{
86
- bounds[2 * dim + 1 ].GetValue (&instance).value_or (0 )};
87
- extent[dim] = ub >= lb ? ub - lb + 1 : 0 ;
88
- }
93
+ SubscriptValue extents[maxRank];
94
+ GetComponentExtents (extents, comp, instance);
89
95
StaticDescriptor<maxRank, true , 0 > staticDescriptor;
90
96
Descriptor &compDesc{staticDescriptor.descriptor ()};
91
97
const typeInfo::DerivedType &compType{*comp.derivedType ()};
92
98
for (std::size_t j{0 }; j++ < elements; instance.IncrementSubscripts (at)) {
93
99
compDesc.Establish (compType,
94
100
instance.ElementComponent <char >(at, comp.offset ()), comp.rank (),
95
- extent );
101
+ extents );
96
102
stat = Initialize (compDesc, compType, terminator, hasStat, errMsg);
97
103
if (stat != StatOk) {
98
104
break ;
@@ -253,22 +259,16 @@ RT_API_ATTRS void Finalize(const Descriptor &descriptor,
253
259
}
254
260
} else if (comp.genre () == typeInfo::Component::Genre::Data &&
255
261
comp.derivedType () && !comp.derivedType ()->noFinalizationNeeded ()) {
256
- SubscriptValue extent[maxRank];
257
- const typeInfo::Value *bounds{comp.bounds ()};
258
- for (int dim{0 }; dim < comp.rank (); ++dim) {
259
- SubscriptValue lb{bounds[2 * dim].GetValue (&descriptor).value_or (0 )};
260
- SubscriptValue ub{
261
- bounds[2 * dim + 1 ].GetValue (&descriptor).value_or (0 )};
262
- extent[dim] = ub >= lb ? ub - lb + 1 : 0 ;
263
- }
262
+ SubscriptValue extents[maxRank];
263
+ GetComponentExtents (extents, comp, descriptor);
264
264
StaticDescriptor<maxRank, true , 0 > staticDescriptor;
265
265
Descriptor &compDesc{staticDescriptor.descriptor ()};
266
266
const typeInfo::DerivedType &compType{*comp.derivedType ()};
267
267
for (std::size_t j{0 }; j++ < elements;
268
268
descriptor.IncrementSubscripts (at)) {
269
269
compDesc.Establish (compType,
270
270
descriptor.ElementComponent <char >(at, comp.offset ()), comp.rank (),
271
- extent );
271
+ extents );
272
272
Finalize (compDesc, compType, terminator);
273
273
}
274
274
}
@@ -296,6 +296,8 @@ RT_API_ATTRS void Destroy(const Descriptor &descriptor, bool finalize,
296
296
if (finalize && !derived.noFinalizationNeeded ()) {
297
297
Finalize (descriptor, derived, terminator);
298
298
}
299
+ // Deallocate all direct and indirect allocatable and automatic components.
300
+ // Contrary to finalization, the order of deallocation does not matter.
299
301
const Descriptor &componentDesc{derived.component ()};
300
302
std::size_t myComponents{componentDesc.Elements ()};
301
303
std::size_t elements{descriptor.Elements ()};
@@ -304,14 +306,33 @@ RT_API_ATTRS void Destroy(const Descriptor &descriptor, bool finalize,
304
306
for (std::size_t k{0 }; k < myComponents; ++k) {
305
307
const auto &comp{
306
308
*componentDesc.ZeroBasedIndexedElement <typeInfo::Component>(k)};
309
+ const bool destroyComp{
310
+ comp.derivedType () && !comp.derivedType ()->noDestructionNeeded ()};
307
311
if (comp.genre () == typeInfo::Component::Genre::Allocatable ||
308
312
comp.genre () == typeInfo::Component::Genre::Automatic) {
309
313
for (std::size_t j{0 }; j < elements; ++j) {
310
314
Descriptor *d{
311
315
descriptor.ElementComponent <Descriptor>(at, comp.offset ())};
316
+ if (destroyComp) {
317
+ Destroy (*d, /* finalize=*/ false , *comp.derivedType (), terminator);
318
+ }
312
319
d->Deallocate ();
313
320
descriptor.IncrementSubscripts (at);
314
321
}
322
+ } else if (destroyComp &&
323
+ comp.genre () == typeInfo::Component::Genre::Data) {
324
+ SubscriptValue extents[maxRank];
325
+ GetComponentExtents (extents, comp, descriptor);
326
+ StaticDescriptor<maxRank, true , 0 > staticDescriptor;
327
+ Descriptor &compDesc{staticDescriptor.descriptor ()};
328
+ const typeInfo::DerivedType &compType{*comp.derivedType ()};
329
+ for (std::size_t j{0 }; j++ < elements;
330
+ descriptor.IncrementSubscripts (at)) {
331
+ compDesc.Establish (compType,
332
+ descriptor.ElementComponent <char >(at, comp.offset ()), comp.rank (),
333
+ extents);
334
+ Destroy (compDesc, /* finalize=*/ false , *comp.derivedType (), terminator);
335
+ }
315
336
}
316
337
}
317
338
}
0 commit comments