59
59
// should be added to handle it, and `walkCaptureCategories` should be updated
60
60
// to dispatch this new kind of variable to this new class.
61
61
62
+ // / Is \p sym a derived type entity with length parameters ?
63
+ static bool isDerivedWithLenParameters (const Fortran::semantics::Symbol &sym) {
64
+ if (const auto *declTy = sym.GetType ())
65
+ if (const auto *derived = declTy->AsDerived ())
66
+ return Fortran::semantics::CountLenParameters (*derived) != 0 ;
67
+ return false ;
68
+ }
69
+
70
+ // / Map the extracted fir::ExtendedValue for a host associated variable inside
71
+ // / and internal procedure to its symbol. Generates an hlfir.declare in HLFIR.
72
+ static void bindCapturedSymbol (const Fortran::semantics::Symbol &sym,
73
+ fir::ExtendedValue val,
74
+ Fortran::lower::AbstractConverter &converter,
75
+ Fortran::lower::SymMap &symMap) {
76
+ if (converter.getLoweringOptions ().getLowerToHighLevelFIR ()) {
77
+ // TODO: add an indication that this is a host variable in the declare to
78
+ // allow alias analysis to detect this case.
79
+ Fortran::lower::genDeclareSymbol (converter, symMap, sym, val);
80
+ } else {
81
+ symMap.addSymbol (sym, val);
82
+ }
83
+ }
84
+
85
+ namespace {
62
86
// / Struct to be used as argument in walkCaptureCategories when building the
63
87
// / tuple element type for a host associated variable.
64
88
struct GetTypeInTuple {
@@ -146,10 +170,10 @@ class CapturedSimpleScalars : public CapturedSymbols<CapturedSimpleScalars> {
146
170
}
147
171
148
172
static void getFromTuple (const GetFromTuple &args,
149
- Fortran::lower::AbstractConverter &,
173
+ Fortran::lower::AbstractConverter &converter ,
150
174
const Fortran::semantics::Symbol &sym,
151
175
const Fortran::lower::BoxAnalyzer &) {
152
- args. symMap . addSymbol (sym, args.valueInTuple );
176
+ bindCapturedSymbol (sym, args.valueInTuple , converter, args. symMap );
153
177
}
154
178
};
155
179
@@ -177,10 +201,10 @@ class CapturedProcedure : public CapturedSymbols<CapturedProcedure> {
177
201
}
178
202
179
203
static void getFromTuple (const GetFromTuple &args,
180
- Fortran::lower::AbstractConverter &,
204
+ Fortran::lower::AbstractConverter &converter ,
181
205
const Fortran::semantics::Symbol &sym,
182
206
const Fortran::lower::BoxAnalyzer &) {
183
- args. symMap . addSymbol (sym, args.valueInTuple );
207
+ bindCapturedSymbol (sym, args.valueInTuple , converter, args. symMap );
184
208
}
185
209
};
186
210
@@ -223,14 +247,6 @@ class CapturedCharacterScalars
223
247
}
224
248
};
225
249
226
- // / Is \p sym a derived type entity with length parameters ?
227
- static bool isDerivedWithLenParameters (const Fortran::semantics::Symbol &sym) {
228
- if (const auto *declTy = sym.GetType ())
229
- if (const auto *derived = declTy->AsDerived ())
230
- return Fortran::semantics::CountLenParameters (*derived) != 0 ;
231
- return false ;
232
- }
233
-
234
250
// / Class defining how polymorphic entities are captured in internal procedures.
235
251
// / Polymorphic entities are always boxed as a fir.class box.
236
252
class CapturedPolymorphic : public CapturedSymbols <CapturedPolymorphic> {
@@ -253,7 +269,7 @@ class CapturedPolymorphic : public CapturedSymbols<CapturedPolymorphic> {
253
269
Fortran::lower::AbstractConverter &converter,
254
270
const Fortran::semantics::Symbol &sym,
255
271
const Fortran::lower::BoxAnalyzer &ba) {
256
- args. symMap . addSymbol (sym, args.valueInTuple );
272
+ bindCapturedSymbol (sym, args.valueInTuple , converter, args. symMap );
257
273
}
258
274
};
259
275
@@ -306,8 +322,9 @@ class CapturedAllocatableAndPointer
306
322
TODO (loc, " host associated derived type allocatable or pointer with "
307
323
" length parameters" );
308
324
}
309
- args.symMap .addSymbol (
310
- sym, fir::MutableBoxValue (args.valueInTuple , nonDeferredLenParams, {}));
325
+ bindCapturedSymbol (
326
+ sym, fir::MutableBoxValue (args.valueInTuple , nonDeferredLenParams, {}),
327
+ converter, args.symMap );
311
328
}
312
329
};
313
330
@@ -389,8 +406,9 @@ class CapturedArrays : public CapturedSymbols<CapturedArrays> {
389
406
390
407
if (canReadCapturedBoxValue (converter, sym)) {
391
408
fir::BoxValue boxValue (box, lbounds, /* explicitParams=*/ std::nullopt);
392
- args.symMap .addSymbol (sym,
393
- fir::factory::readBoxValue (builder, loc, boxValue));
409
+ bindCapturedSymbol (sym,
410
+ fir::factory::readBoxValue (builder, loc, boxValue),
411
+ converter, args.symMap );
394
412
} else {
395
413
// Keep variable as a fir.box.
396
414
// If this is an optional that is absent, the fir.box needs to be an
@@ -409,7 +427,7 @@ class CapturedArrays : public CapturedSymbols<CapturedArrays> {
409
427
absentBox);
410
428
}
411
429
fir::BoxValue boxValue (box, lbounds, /* explicitParams=*/ std::nullopt);
412
- args. symMap . addSymbol (sym, boxValue);
430
+ bindCapturedSymbol (sym, boxValue, converter, args. symMap );
413
431
}
414
432
}
415
433
@@ -430,13 +448,14 @@ class CapturedArrays : public CapturedSymbols<CapturedArrays> {
430
448
!isDerivedWithLenParameters (sym);
431
449
}
432
450
};
451
+ } // namespace
433
452
434
453
// / Dispatch \p visitor to the CapturedSymbols which is handling how host
435
454
// / association is implemented for this kind of symbols. This ensures the same
436
455
// / dispatch decision is taken when building the tuple type, when creating the
437
456
// / tuple, and when instantiating host associated variables from it.
438
457
template <typename T>
439
- typename T::Result
458
+ static typename T::Result
440
459
walkCaptureCategories (T visitor, Fortran::lower::AbstractConverter &converter,
441
460
const Fortran::semantics::Symbol &sym) {
442
461
if (isDerivedWithLenParameters (sym))
0 commit comments