diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp index 53745d10fe9e4..80efa527382ab 100644 --- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp +++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp @@ -190,6 +190,33 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertSequenceType( /* associated */ nullptr); } +mlir::LLVM::DITypeAttr DebugTypeGenerator::convertCharacterType( + fir::CharacterType charTy, mlir::LLVM::DIFileAttr fileAttr, + mlir::LLVM::DIScopeAttr scope, mlir::Location loc) { + mlir::MLIRContext *context = module.getContext(); + if (!charTy.hasConstantLen()) + return genPlaceholderType(context); + + // DWARF 5 says the following about the character encoding in 5.1.1.2. + // "DW_ATE_ASCII and DW_ATE_UCS specify encodings for the Fortran 2003 + // string kinds ASCII (ISO/IEC 646:1991) and ISO_10646 (UCS-4 in ISO/IEC + // 10646:2000)." + unsigned encoding = llvm::dwarf::DW_ATE_ASCII; + if (charTy.getFKind() != 1) + encoding = llvm::dwarf::DW_ATE_UCS; + + // FIXME: Currently the DIStringType in llvm does not have the option to set + // type of the underlying character. This restricts out ability to represent + // string with non-default characters. Please see issue #95440 for more + // details. + return mlir::LLVM::DIStringTypeAttr::get( + context, llvm::dwarf::DW_TAG_string_type, + mlir::StringAttr::get(context, ""), + charTy.getLen() * kindMapping.getCharacterBitsize(charTy.getFKind()), + /*alignInBits=*/0, /*stringLength=*/nullptr, + /*stringLengthExp=*/nullptr, /*stringLocationExp=*/nullptr, encoding); +} + mlir::LLVM::DITypeAttr DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr, mlir::LLVM::DIScopeAttr scope, @@ -224,6 +251,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr, bitWidth * 2, llvm::dwarf::DW_ATE_complex_float); } else if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(Ty)) { return convertSequenceType(seqTy, fileAttr, scope, loc); + } else if (auto charTy = mlir::dyn_cast_or_null<fir::CharacterType>(Ty)) { + return convertCharacterType(charTy, fileAttr, scope, loc); } else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) { auto elTy = boxTy.getElementType(); if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy)) diff --git a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h index 11515d11dfed6..aa26694ab5114 100644 --- a/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h +++ b/flang/lib/Optimizer/Transforms/DebugTypeGenerator.h @@ -45,6 +45,10 @@ class DebugTypeGenerator { mlir::LLVM::DIFileAttr fileAttr, mlir::LLVM::DIScopeAttr scope, mlir::Location loc, bool genAllocated, bool genAssociated); + mlir::LLVM::DITypeAttr convertCharacterType(fir::CharacterType charTy, + mlir::LLVM::DIFileAttr fileAttr, + mlir::LLVM::DIScopeAttr scope, + mlir::Location loc); mlir::ModuleOp module; KindMapping kindMapping; std::uint64_t dimsSize; diff --git a/flang/test/Integration/debug-char-type-1.f90 b/flang/test/Integration/debug-char-type-1.f90 new file mode 100644 index 0000000000000..a0aebd3125c6e --- /dev/null +++ b/flang/test/Integration/debug-char-type-1.f90 @@ -0,0 +1,21 @@ +! RUN: %flang_fc1 -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s + +module helper + character(len=40) :: str +end module helper + +program test + use helper + character(kind=4, len=8) :: first + character(len=10) :: second + first = '3.14 = π' + second = 'Fortran' + str = 'Hello World!' +end program test + +! CHECK-DAG: !DIGlobalVariable(name: "str"{{.*}}type: ![[TY40:[0-9]+]]{{.*}}) +! CHECK-DAG: ![[TY40]] = !DIStringType(size: 320, encoding: DW_ATE_ASCII) +! CHECK-DAG: !DILocalVariable(name: "first"{{.*}}type: ![[TY8:[0-9]+]]) +! CHECK-DAG: ![[TY8]] = !DIStringType(size: 256, encoding: DW_ATE_UCS) +! CHECK-DAG: !DILocalVariable(name: "second"{{.*}}type: ![[TY10:[0-9]+]]) +! CHECK-DAG: ![[TY10]] = !DIStringType(size: 80, encoding: DW_ATE_ASCII) \ No newline at end of file diff --git a/flang/test/Transforms/debug-char-type-1.fir b/flang/test/Transforms/debug-char-type-1.fir new file mode 100644 index 0000000000000..cdce3b7b8b334 --- /dev/null +++ b/flang/test/Transforms/debug-char-type-1.fir @@ -0,0 +1,19 @@ +// RUN: fir-opt --add-debug-info --mlir-print-debuginfo %s | FileCheck %s + +module attributes {dlti.dl_spec = #dlti.dl_spec<>} { + fir.global @_QMhelperEstr1 : !fir.char<1,40> { + %0 = fir.zero_bits !fir.char<1,40> + fir.has_value %0 : !fir.char<1,40> + } loc(#loc1) + fir.global @_QMhelperEstr2 : !fir.char<4,20> { + %0 = fir.zero_bits !fir.char<4,20> + fir.has_value %0 : !fir.char<4,20> + } loc(#loc1) +} +#loc1 = loc("string.f90":1:1) + +// CHECK-DAG: #[[TY1:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 320, encoding = DW_ATE_ASCII> +// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str1"{{.*}}type = #[[TY1]]{{.*}}> +// CHECK-DAG: #[[TY2:.*]] = #llvm.di_string_type<tag = DW_TAG_string_type, name = "", sizeInBits = 640, encoding = DW_ATE_UCS> +// CHECK-DAG: #llvm.di_global_variable<{{.*}}name = "str2"{{.*}}type = #[[TY2]]{{.*}}> +