@@ -271,6 +271,19 @@ static bool canCacheThisType(mlir::LLVM::DICompositeTypeAttr comTy) {
271
271
return true ;
272
272
}
273
273
274
+ std::pair<std::uint64_t , unsigned short >
275
+ DebugTypeGenerator::getFieldSizeAndAlign (mlir::Type fieldTy) {
276
+ mlir::Type llvmTy;
277
+ if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(fieldTy))
278
+ llvmTy = llvmTypeConverter.convertBoxTypeAsStruct (boxTy, getBoxRank (boxTy));
279
+ else
280
+ llvmTy = llvmTypeConverter.convertType (fieldTy);
281
+
282
+ uint64_t byteSize = dataLayout->getTypeSize (llvmTy);
283
+ unsigned short byteAlign = dataLayout->getTypeABIAlignment (llvmTy);
284
+ return std::pair{byteSize, byteAlign};
285
+ }
286
+
274
287
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType (
275
288
fir::RecordType Ty, mlir::LLVM::DIFileAttr fileAttr,
276
289
mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -303,15 +316,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
303
316
mlir::IntegerType intTy = mlir::IntegerType::get (context, 64 );
304
317
std::uint64_t offset = 0 ;
305
318
for (auto [fieldName, fieldTy] : Ty.getTypeList ()) {
306
- mlir::Type llvmTy;
307
- if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(fieldTy))
308
- llvmTy =
309
- llvmTypeConverter.convertBoxTypeAsStruct (boxTy, getBoxRank (boxTy));
310
- else
311
- llvmTy = llvmTypeConverter.convertType (fieldTy);
312
-
313
- uint64_t byteSize = dataLayout->getTypeSize (llvmTy);
314
- unsigned short byteAlign = dataLayout->getTypeABIAlignment (llvmTy);
319
+ auto [byteSize, byteAlign] = getFieldSizeAndAlign (fieldTy);
315
320
std::optional<llvm::ArrayRef<int64_t >> lowerBounds =
316
321
fir::getComponentLowerBoundsIfNonDefault (Ty, fieldName, module,
317
322
symbolTable);
@@ -368,6 +373,42 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
368
373
return finalAttr;
369
374
}
370
375
376
+ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertTupleType (
377
+ mlir::TupleType Ty, mlir::LLVM::DIFileAttr fileAttr,
378
+ mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
379
+ // Check if this type has already been converted.
380
+ auto iter = typeCache.find (Ty);
381
+ if (iter != typeCache.end ())
382
+ return iter->second ;
383
+
384
+ llvm::SmallVector<mlir::LLVM::DINodeAttr> elements;
385
+ mlir::MLIRContext *context = module.getContext ();
386
+
387
+ std::uint64_t offset = 0 ;
388
+ for (auto fieldTy : Ty.getTypes ()) {
389
+ auto [byteSize, byteAlign] = getFieldSizeAndAlign (fieldTy);
390
+ mlir::LLVM::DITypeAttr elemTy =
391
+ convertType (fieldTy, fileAttr, scope, /* declOp=*/ nullptr );
392
+ offset = llvm::alignTo (offset, byteAlign);
393
+ mlir::LLVM::DIDerivedTypeAttr tyAttr = mlir::LLVM::DIDerivedTypeAttr::get (
394
+ context, llvm::dwarf::DW_TAG_member, mlir::StringAttr::get (context, " " ),
395
+ elemTy, byteSize * 8 , byteAlign * 8 , offset * 8 ,
396
+ /* optional<address space>=*/ std::nullopt,
397
+ /* extra data=*/ nullptr );
398
+ elements.push_back (tyAttr);
399
+ offset += llvm::alignTo (byteSize, byteAlign);
400
+ }
401
+
402
+ auto typeAttr = mlir::LLVM::DICompositeTypeAttr::get (
403
+ context, llvm::dwarf::DW_TAG_structure_type,
404
+ mlir::StringAttr::get (context, " " ), fileAttr, /* line=*/ 0 , scope,
405
+ /* baseType=*/ nullptr , mlir::LLVM::DIFlags::Zero, offset * 8 ,
406
+ /* alignInBits=*/ 0 , elements, /* dataLocation=*/ nullptr , /* rank=*/ nullptr ,
407
+ /* allocated=*/ nullptr , /* associated=*/ nullptr );
408
+ typeCache[Ty] = typeAttr;
409
+ return typeAttr;
410
+ }
411
+
371
412
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType (
372
413
fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
373
414
mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -574,6 +615,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
574
615
/* hasDescriptor=*/ false );
575
616
} else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(Ty)) {
576
617
return convertRecordType (recTy, fileAttr, scope, declOp);
618
+ } else if (auto tupleTy = mlir::dyn_cast_if_present<mlir::TupleType>(Ty)) {
619
+ return convertTupleType (tupleTy, fileAttr, scope, declOp);
577
620
} else if (auto refTy = mlir::dyn_cast_if_present<fir::ReferenceType>(Ty)) {
578
621
auto elTy = refTy.getEleTy ();
579
622
return convertPointerLikeType (elTy, fileAttr, scope, declOp,
0 commit comments