@@ -271,6 +271,19 @@ static bool canCacheThisType(mlir::LLVM::DICompositeTypeAttr comTy) {
271271 return true ;
272272}
273273
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+
274287mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType (
275288 fir::RecordType Ty, mlir::LLVM::DIFileAttr fileAttr,
276289 mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -303,15 +316,7 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
303316 mlir::IntegerType intTy = mlir::IntegerType::get (context, 64 );
304317 std::uint64_t offset = 0 ;
305318 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);
315320 std::optional<llvm::ArrayRef<int64_t >> lowerBounds =
316321 fir::getComponentLowerBoundsIfNonDefault (Ty, fieldName, module ,
317322 symbolTable);
@@ -368,6 +373,42 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType(
368373 return finalAttr;
369374}
370375
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+
371412mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType (
372413 fir::SequenceType seqTy, mlir::LLVM::DIFileAttr fileAttr,
373414 mlir::LLVM::DIScopeAttr scope, fir::cg::XDeclareOp declOp) {
@@ -574,6 +615,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
574615 /* hasDescriptor=*/ false );
575616 } else if (auto recTy = mlir::dyn_cast_or_null<fir::RecordType>(Ty)) {
576617 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);
577620 } else if (auto refTy = mlir::dyn_cast_if_present<fir::ReferenceType>(Ty)) {
578621 auto elTy = refTy.getEleTy ();
579622 return convertPointerLikeType (elTy, fileAttr, scope, declOp,
0 commit comments