Skip to content

Commit 030179c

Browse files
authored
[flang][debug] Support ClassType. (#114809)
This PR adds the handling of `ClassType`. It is treated as pointer to the underlying type. Note that `ClassType` when passed to the function have double indirection so it is represented as pointer to type (compared to other types which may have a single indirection). If `ClassType` wraps a pointer or allocatable then we take care to generate it as PTR -> type (and not PTR -> PTR -> type). This is how it looks like in the debugger. ``` subroutine test_proc (this) class(test_type), intent (inout) :: this allocate (this%b (3, 2)) call fill_array_2d (this%b) print *, this%a end ``` ``` (gdb) p this $6 = (PTR TO -> ( Type test_type )) 0x2052a0 (gdb) p this%a $7 = 0 (gdb) p this%b $8 = ((1, 2, 3) (4, 5, 6)) ```
1 parent ad3b291 commit 030179c

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

flang/lib/Optimizer/Transforms/DebugTypeGenerator.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,12 @@ mlir::LLVM::DITypeAttr DebugTypeGenerator::convertPointerLikeType(
629629
return convertCharacterType(charTy, fileAttr, scope, declOp,
630630
/*hasDescriptor=*/true);
631631

632-
mlir::LLVM::DITypeAttr elTyAttr = convertType(elTy, fileAttr, scope, declOp);
632+
// If elTy is null or none then generate a void*
633+
mlir::LLVM::DITypeAttr elTyAttr;
634+
if (!elTy || mlir::isa<mlir::NoneType>(elTy))
635+
elTyAttr = mlir::LLVM::DINullTypeAttr::get(context);
636+
else
637+
elTyAttr = convertType(elTy, fileAttr, scope, declOp);
633638

634639
return mlir::LLVM::DIDerivedTypeAttr::get(
635640
context, llvm::dwarf::DW_TAG_pointer_type,
@@ -679,8 +684,8 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
679684
return genBasicType(context, mlir::StringAttr::get(context, "integer"),
680685
llvmTypeConverter.getIndexTypeBitwidth(),
681686
llvm::dwarf::DW_ATE_signed);
682-
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BoxType>(Ty)) {
683-
auto elTy = boxTy.getElementType();
687+
} else if (auto boxTy = mlir::dyn_cast_or_null<fir::BaseBoxType>(Ty)) {
688+
auto elTy = boxTy.getEleTy();
684689
if (auto seqTy = mlir::dyn_cast_or_null<fir::SequenceType>(elTy))
685690
return convertBoxedSequenceType(seqTy, fileAttr, scope, declOp, false,
686691
false);
@@ -692,7 +697,9 @@ DebugTypeGenerator::convertType(mlir::Type Ty, mlir::LLVM::DIFileAttr fileAttr,
692697
return convertPointerLikeType(ptrTy.getElementType(), fileAttr, scope,
693698
declOp, /*genAllocated=*/false,
694699
/*genAssociated=*/true);
695-
return genPlaceholderType(context);
700+
return convertPointerLikeType(elTy, fileAttr, scope, declOp,
701+
/*genAllocated=*/false,
702+
/*genAssociated=*/false);
696703
} else {
697704
// FIXME: These types are currently unhandled. We are generating a
698705
// placeholder type to allow us to test supported bits.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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.type_info @_QTtest_type nofinal : !fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}> dispatch_table {
5+
fir.dt_entry "test_proc", @_QPtest_proc
6+
} loc(#loc1)
7+
func.func private @_QPtest_proc(%arg0: !fir.class<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>)
8+
9+
func.func @test() {
10+
%0 = fir.address_of(@_QFEx) : !fir.ref<!fir.class<!fir.heap<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>
11+
%1 = fircg.ext_declare %0 {uniq_name = "_QFEx"} : (!fir.ref<!fir.class<!fir.heap<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>) -> !fir.ref<!fir.class<!fir.heap<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>> loc(#loc3)
12+
%2 = fir.address_of(@_QFEy) : !fir.ref<!fir.class<!fir.ptr<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>
13+
%3 = fircg.ext_declare %2 {uniq_name = "_QFEy"} : (!fir.ref<!fir.class<!fir.ptr<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>>) -> !fir.ref<!fir.class<!fir.ptr<!fir.type<_QTtest_type{a:i32,b:!fir.box<!fir.heap<!fir.array<?x?xf32>>>}>>>> loc(#loc4)
14+
%4 = fir.address_of(@_QFEz) : !fir.ref<!fir.class<none>>
15+
%5 = fircg.ext_declare %4 {uniq_name = "_QFEz"} : (!fir.ref<!fir.class<none>>) -> !fir.ref<!fir.class<none>> loc(#loc4)
16+
%6 = fir.address_of(@_QFEt) : !fir.ref<!fir.class<!fir.ptr<none>>>
17+
%7 = fircg.ext_declare %6 {uniq_name = "_QFEt"} : (!fir.ref<!fir.class<!fir.ptr<none>>>) -> !fir.ref<!fir.class<!fir.ptr<none>>> loc(#loc4)
18+
return
19+
} loc(#loc2)
20+
}
21+
22+
#loc1 = loc("./simple.f90":2:1)
23+
#loc2 = loc("./simple.f90":10:1)
24+
#loc3 = loc("./simple.f90":15:1)
25+
#loc4 = loc("./simple.f90":22:1)
26+
27+
// CHECK-DAG: #[[TY1:.*]] = #llvm.di_composite_type<{{.*}}name = "test_type"{{.*}}>
28+
// CHECK-DAG: #[[TY2:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "", baseType = #[[TY1]]{{.*}}>
29+
// CHECK-DAG: #[[TY3:.*]] = #llvm.di_derived_type<tag = DW_TAG_pointer_type, name = "", baseType = #di_null_type{{.*}}>
30+
// CHECK-DAG: #llvm.di_subroutine_type<callingConvention = DW_CC_normal, types = #di_null_type, #[[TY2]]>
31+
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "x"{{.*}}type = #[[TY2]]>
32+
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "y"{{.*}}type = #[[TY2]]>
33+
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "z"{{.*}}type = #[[TY3]]>
34+
// CHECK-DAG: #llvm.di_local_variable<{{.*}}name = "t"{{.*}}type = #[[TY3]]>

0 commit comments

Comments
 (0)