Skip to content

Commit 7e4f7fc

Browse files
authored
[flang][debug] Support fixed size character type. (#95462)
This PR adds debug support for fixed size character type. The character type gets translated to DIStringType. As I have noticed in comments, currently DIStringType does not have a way to represent the underlying character type of the string. This restricts our ability to represent wide string. As an example, this is how the debugger shows 2 different type of string. Note that non-ascii characters work ok with default kind string. character(kind=4, len=5) :: str1 character(len=16) :: str2 str1 = 'hello' str2 = 'π = 3.14' (gdb) p str1 $1 = 'h\000\000\000e\000\000\000l\000\000\000l\000\000\000o\000\000\000' (gdb) p str2 $2 = 'π = 3.14 '
1 parent f838f08 commit 7e4f7fc

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,33 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType(
190190
/* associated */ nullptr);
191191
}
192192

193+
mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType(
194+
fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr,
195+
mlir::LLVM::DIScopeAttr scope, mlir::Location loc) {
196+
mlir::MLIRContext *context = module.getContext();
197+
if (!charTy.hasConstantLen())
198+
return genPlaceholderType(context);
199+
200+
// DWARF 5 says the following about the character encoding in 5.1.1.2.
201+
// "DW_ATE_ASCII and DW_ATE_UCS specify encodings for the Fortran 2003
202+
// string kinds ASCII (ISO/IEC 646:1991) and ISO_10646 (UCS-4 in ISO/IEC
203+
// 10646:2000)."
204+
unsigned encoding = llvm::dwarf::DW_ATE_ASCII;
205+
if (charTy.getFKind() != 1)
206+
encoding = llvm::dwarf::DW_ATE_UCS;
207+
208+
// FIXME: Currently the DIStringType in llvm does not have the option to set
209+
// type of the underlying character. This restricts out ability to represent
210+
// string with non-default characters. Please see issue #95440 for more
211+
// details.
212+
return mlir::LLVM::DIStringTypeAttr::get(
213+
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);
218+
}
219+
193220
mlir::LLVM::DITypeAttr
194221
DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
195222
mlir::LLVM::DIScopeAttr scope,
@@ -224,6 +251,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
224251
bitWidth * 2, llvm::dwarf::DW_ATE_complex_float);
225252
} else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) {
226253
return convertSequenceType(seqTy, fileAttr, scope, loc);
254+
} else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) {
255+
return convertCharacterType(charTy, fileAttr, scope, loc);
227256
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
228257
auto elTy = boxTy.getElementType();
229258
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))

flang/lib/Optimizer/Transforms/DebugTypeGenerator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class DebugTypeGenerator {
4545
mlir::LLVM::DIFileAttr fileAttr,
4646
mlir::LLVM::DIScopeAttr scope, mlir::Location loc,
4747
bool genAllocated, bool genAssociated);
48+
mlir::LLVM::DITypeAttr convertCharacterType(fir::CharacterType charTy,
49+
mlir::LLVM::DIFileAttr fileAttr,
50+
mlir::LLVM::DIScopeAttr scope,
51+
mlir::Location loc);
4852
mlir::ModuleOp module;
4953
KindMapping kindMapping;
5054
std::uint64_t dimsSize;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
2+
3+
module helper
4+
character(len=40) :: str
5+
end module helper
6+
7+
program test
8+
use helper
9+
character(kind=4, len=8) :: first
10+
character(len=10) :: second
11+
first = '3.14 = π'
12+
second = 'Fortran'
13+
str = 'Hello World!'
14+
end program test
15+
16+
! CHECK-DAG: !DIGlobalVariable(name: "str"{{.*}}type: ![[TY40:[0-9]+]]{{.*}})
17+
! CHECK-DAG: ![[TY40]] = !DIStringType(size: 320, encoding: DW_ATE_ASCII)
18+
! CHECK-DAG: !DILocalVariable(name: "first"{{.*}}type: ![[TY8:[0-9]+]])
19+
! CHECK-DAG: ![[TY8]] = !DIStringType(size: 256, encoding: DW_ATE_UCS)
20+
! CHECK-DAG: !DILocalVariable(name: "second"{{.*}}type: ![[TY10:[0-9]+]])
21+
! CHECK-DAG: ![[TY10]] = !DIStringType(size: 80, encoding: DW_ATE_ASCII)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s
2+
3+
module attributes {dlti.dl_spec = #dlti.dl_spec<>} {
4+
fir.global @_QMhelperEstr1 : !fir.char<1,40> {
5+
%0 = fir.zero_bits !fir.char<1,40>
6+
fir.has_value %0 : !fir.char<1,40>
7+
} loc(#loc1)
8+
fir.global @_QMhelperEstr2 : !fir.char<4,20> {
9+
%0 = fir.zero_bits !fir.char<4,20>
10+
fir.has_value %0 : !fir.char<4,20>
11+
} loc(#loc1)
12+
}
13+
#loc1 = loc("string.f90":1:1)
14+
15+
// CHECK-DAG: #[[TY1:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 320, encoding = DW_ATE_ASCII>
16+
// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str1"{{.*}}type = #[[TY1]]{{.*}}>
17+
// CHECK-DAG: #[[TY2:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 640, encoding = DW_ATE_UCS>
18+
// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str2"{{.*}}type = #[[TY2]]{{.*}}>
19+

0 commit comments

Comments
 (0)