Skip to content

Commit 3a57925

Browse files
authored
[flang][debug] Handle allocatable strings. (#95906)
The allocatable strings also use DIStringType but provide dwarf expressions to find the location and length of the string. With this change in place, the debugging of the allocatable strings looks like this: character(len=:), allocatable :: first character(len=:), allocatable :: second character(len=:), allocatable :: third first = 'Mount' second = 'Everest' third = first // " " // second print *, third (gdb) p third $1 = "" (gdb) n 18 print *, third (gdb) p third $2 = 'Mount Everest' (gdb) ptype third type = character (13)
1 parent cb248f8 commit 3a57925

File tree

4 files changed

+50
-11
lines changed

4 files changed

+50
-11
lines changed

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ DebugTypeGenerator::DebugTypeGenerator(mlir::ModuleOp m)
6161
// descriptors like lower_bound and extent for each dimension.
6262
mlir::Type llvmDimsType = getDescFieldTypeModel<kDimsPosInBox>()(context);
6363
mlir::Type llvmPtrType = getDescFieldTypeModel<kAddrPosInBox>()(context);
64+
mlir::Type llvmLenType = getDescFieldTypeModel<kElemLenPosInBox>()(context);
6465
dimsOffset = getComponentOffset<kDimsPosInBox>(*dl, context, llvmDimsType);
6566
dimsSize = dl->getTypeSize(llvmDimsType);
6667
ptrSize = dl->getTypeSize(llvmPtrType);
68+
lenOffset = getComponentOffset<kElemLenPosInBox>(*dl, context, llvmLenType);
6769
}
6870

6971
static mlir::LLVM::DITypeAttr genBasicType(mlir::MLIRContext *context,
@@ -192,10 +194,8 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
192194

193195
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
194196
fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
195-
mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
197+
mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool hasDescriptor) {
196198
mlir::MLIRContext *context = module.getContext();
197-
if (!charTy.hasConstantLen())
198-
return genPlaceholderType(context);
199199

200200
// DWARF 5 says the following about the character encoding in 5.1.1.2.
201201
// "DW_ATE_ASCII and DW_ATE_UCS specify encodings for the Fortran 2003
@@ -205,16 +205,38 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
205205
if (charTy.getFKind() != 1)
206206
encoding = llvm::dwarf::DW_ATE_UCS;
207207

208+
uint64_t sizeInBits = 0;
209+
mlir::LLVM::DIExpressionAttr lenExpr = nullptr;
210+
mlir::LLVM::DIExpressionAttr locExpr = nullptr;
211+
212+
if (hasDescriptor) {
213+
llvm::SmallVector<mlir::LLVM::DIExpressionElemAttr> ops;
214+
auto addOp = [&](unsigned opc, llvm::ArrayRef<uint64_t> vals) {
215+
ops.push_back(mlir::LLVM::DIExpressionElemAttr::get(context, opc, vals));
216+
};
217+
addOp(llvm::dwarf::DW_OP_push_object_address, {});
218+
addOp(llvm::dwarf::DW_OP_plus_uconst, {lenOffset});
219+
lenExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
220+
ops.clear();
221+
222+
addOp(llvm::dwarf::DW_OP_push_object_address, {});
223+
addOp(llvm::dwarf::DW_OP_deref, {});
224+
locExpr = mlir::LLVM::DIExpressionAttr::get(context, ops);
225+
} else if (charTy.hasConstantLen()) {
226+
sizeInBits =
227+
charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind());
228+
} else {
229+
return genPlaceholderType(context);
230+
}
231+
208232
// FIXME: Currently the DIStringType in llvm does not have the option to set
209233
// type of the underlying character. This restricts out ability to represent
210234
// string with non-default characters. Please see issue #95440 for more
211235
// details.
212236
return mlir::LLVM::DIStringTypeAttr::get(
213237
context, llvm::dwarf::DW_TAG_string_type,
214-
mlir::StringAttr::get(context, ""),
215-
charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind()),
216-
/*alignInBits=*/0, /*stringLength=*/nullptr,
217-
/*stringLengthExp=*/nullptr, /*stringLocationExp=*/nullptr, encoding);
238+
mlir::StringAttr::get(context, ""), sizeInBits, /*alignInBits=*/0,
239+
/*stringLength=*/nullptr, lenExpr, locExpr, encoding);
218240
}
219241

220242
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
@@ -229,6 +251,9 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
229251
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
230252
return convertBoxedSequenceType(seqTy, fileAttr, scope, loc, genAllocated,
231253
genAssociated);
254+
if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(elTy))
255+
return convertCharacterType(charTy, fileAttr, scope, loc,
256+
/*hasDescriptor=*/true);
232257

233258
mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, loc);
234259

@@ -274,7 +299,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
274299
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
275300
return convertSequenceType(seqTy, fileAttr, scope, loc);
276301
} else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) {
277-
return convertCharacterType(charTy, fileAttr, scope, loc);
302+
return convertCharacterType(charTy, fileAttr, scope, loc,
303+
/*hasDescriptor=*/false);
278304
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
279305
auto elTy = boxTy.getElementType();
280306
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))

flang/lib/Optimizer/Transforms/DebugTypeGenerator.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ class DebugTypeGenerator {
4848
mlir::LLVM::DITypeAttr convertCharacterType(fir::CharacterType charTy,
4949
mlir::LLVM::DIFileAttr fileAttr,
5050
mlir::LLVM::DIScopeAttr scope,
51-
mlir::Location loc);
51+
mlir::Location loc,
52+
bool hasDescriptor);
5253

5354
mlir::LLVM::DITypeAttr
5455
convertPointerLikeType(mlir::Type elTy, mlir::LLVM::DIFileAttr fileAttr,
@@ -60,6 +61,7 @@ class DebugTypeGenerator {
6061
std::uint64_t dimsSize;
6162
std::uint64_t dimsOffset;
6263
std::uint64_t ptrSize;
64+
std::uint64_t lenOffset;
6365
};
6466

6567
} // namespace fir

flang/test/Integration/debug-char-type-1.f90

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
module helper
44
character(len=40) :: str
5+
character(len=:), allocatable :: str2
56
end module helper
67

78
program test
@@ -11,11 +12,14 @@ program test
1112
first = '3.14 = π'
1213
second = 'Fortran'
1314
str = 'Hello World!'
15+
str2 = 'A quick brown fox jumps over a lazy dog'
1416
end program test
1517

1618
! CHECK-DAG: !DIGlobalVariable(name: "str"{{.*}}type: ![[TY40:[0-9]+]]{{.*}})
1719
! CHECK-DAG: ![[TY40]] = !DIStringType(size: 320, encoding: DW_ATE_ASCII)
20+
! CHECK-DAG: !DIGlobalVariable(name: "str2"{{.*}}type: ![[TY:[0-9]+]]{{.*}})
21+
! CHECK-DAG: ![[TY]] = !DIStringType(stringLengthExpression: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8), stringLocationExpression: !DIExpression(DW_OP_push_object_address, DW_OP_deref), encoding: DW_ATE_ASCII)
1822
! CHECK-DAG: !DILocalVariable(name: "first"{{.*}}type: ![[TY8:[0-9]+]])
1923
! CHECK-DAG: ![[TY8]] = !DIStringType(size: 256, encoding: DW_ATE_UCS)
2024
! CHECK-DAG: !DILocalVariable(name: "second"{{.*}}type: ![[TY10:[0-9]+]])
21-
! CHECK-DAG: ![[TY10]] = !DIStringType(size: 80, encoding: DW_ATE_ASCII)
25+
! CHECK-DAG: ![[TY10]] = !DIStringType(size: 80, encoding: DW_ATE_ASCII)

flang/test/Transforms/debug-char-type-1.fir

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,18 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
99
%0 = fir.zero_bits !fir.char<4,20>
1010
fir.has_value %0 : !fir.char<4,20>
1111
} loc(#loc1)
12+
fir.global @_QMhelperEstr3 : !fir.box<!fir.heap<!fir.char<1,?>>> {
13+
%c0 = arith.constant 0 : index
14+
%0 = fir.zero_bits !fir.heap<!fir.char<1,?>>
15+
%1 = fir.embox %0 typeparams %c0 : (!fir.heap<!fir.char<1,?>>, index) -> !fir.box<!fir.heap<!fir.char<1,?>>>
16+
fir.has_value %1 : !fir.box<!fir.heap<!fir.char<1,?>>>
17+
} loc(#loc1)
1218
}
1319
#loc1 = loc("string.f90":1:1)
1420

1521
// CHECK-DAG: #[[TY1:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 320, encoding = DW_ATE_ASCII>
1622
// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str1"{{.*}}type = #[[TY1]]{{.*}}>
1723
// CHECK-DAG: #[[TY2:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 640, encoding = DW_ATE_UCS>
1824
// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str2"{{.*}}type = #[[TY2]]{{.*}}>
19-
25+
// CHECK-DAG: #[[TY3:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type{{.*}}stringLengthExp = <[DW_OP_push_object_address, DW_OP_plus_uconst(8)]>, stringLocationExp = <[DW_OP_push_object_address, DW_OP_deref]>, encoding = DW_ATE_ASCII>
26+
// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str3"{{.*}}type = #[[TY3]]{{.*}}>

0 commit comments

Comments
 (0)