diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp index 18a47069f5169..83f33a1e3e2a3 100644 --- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp +++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp @@ -315,25 +315,31 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertRecordType( std::optional> lowerBounds = fir::getComponentLowerBoundsIfNonDefault(Ty, fieldName, module, symbolTable); + auto seqTy = mlir::dyn_cast_or_null(fieldTy); // For members of the derived types, the information about the shift in // lower bounds is not part of the declOp but has to be extracted from the - // TypeInfoOp (using getComponentLowerBoundsIfNonDefault). We then assign it - // temporarily to the declOp to propagate this information where it will be - // needed by the type conversion logic. + // TypeInfoOp (using getComponentLowerBoundsIfNonDefault). mlir::LLVM::DITypeAttr elemTy; - if (declOp && lowerBounds) { - llvm::SmallVector shiftOpers; - for (int64_t bound : *lowerBounds) { - auto constOp = builder.create( - module.getLoc(), builder.getIntegerAttr(intTy, bound)); - shiftOpers.push_back(constOp); + if (lowerBounds && seqTy && + lowerBounds->size() == seqTy.getShape().size()) { + llvm::SmallVector elements; + for (auto [bound, dim] : + llvm::zip_equal(*lowerBounds, seqTy.getShape())) { + auto countAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, dim)); + auto lowerAttr = mlir::IntegerAttr::get(intTy, llvm::APInt(64, bound)); + auto subrangeTy = mlir::LLVM::DISubrangeAttr::get( + context, countAttr, lowerAttr, /*upperBound=*/nullptr, + /*stride=*/nullptr); + elements.push_back(subrangeTy); } - mlir::OperandRange originalShift = declOp.getShift(); - mlir::MutableOperandRange mutableOpRange = declOp.getShiftMutable(); - mutableOpRange.assign(shiftOpers); - elemTy = convertType(fieldTy, fileAttr, scope, declOp); - mutableOpRange.assign(originalShift); + elemTy = mlir::LLVM::DICompositeTypeAttr::get( + context, llvm::dwarf::DW_TAG_array_type, /*name=*/nullptr, + /*file=*/nullptr, /*line=*/0, /*scope=*/nullptr, + convertType(seqTy.getEleTy(), fileAttr, scope, declOp), + mlir::LLVM::DIFlags::Zero, /*sizeInBits=*/0, /*alignInBits=*/0, + elements, /*dataLocation=*/nullptr, /*rank=*/nullptr, + /*allocated=*/nullptr, /*associated=*/nullptr); } else elemTy = convertType(fieldTy, fileAttr, scope, /*declOp=*/nullptr); offset = llvm::alignTo(offset, byteAlign); diff --git a/flang/test/Transforms/debug-derived-type-2.fir b/flang/test/Transforms/debug-derived-type-2.fir new file mode 100644 index 0000000000000..63e842619edbe --- /dev/null +++ b/flang/test/Transforms/debug-derived-type-2.fir @@ -0,0 +1,16 @@ +// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s + +module attributes {dlti.dl_spec = #dlti.dl_spec<>} { + fir.global @_QMmEvar : !fir.type<_QMmTt1{elm:!fir.array<5xi32>,elm2:!fir.array<5x8xi32>}> {} loc(#loc1) + fir.type_info @_QMmTt1 noinit nodestroy nofinal : !fir.type<_QMmTt1{elm:!fir.array<5xi32>,elm2:!fir.array<5x8xi32>}> component_info { + fir.dt_component "elm" lbs [2] + fir.dt_component "elm2" lbs [1, 3] + } loc(#loc1) +} +#loc1 = loc("derived.f90":24:1) + + +// CHECK-DAG: #[[TY1:.*]] = #llvm.di_composite_type> +// CHECK-DAG: #[[TY2:.*]] = #llvm.di_composite_type, #llvm.di_subrange> +// CHECK-DAG: #llvm.di_derived_type +// CHECK-DAG: #llvm.di_derived_type