Skip to content

Commit 7906823

Browse files
authored
[DebugInfo] Add DebugTypeArrayDynamic translation (#1871)
This instruction describes a dynamic array, mostly for Fortran 90. Unlike DebugTypeArray it has Data Location, Associated, Allocated and Rank parameters. If the appropriate metadata parameters appear in LLVM IR in DW_TAG_array_type metadata, then such debug type becomes treated as dynamic array by the translator (of course if the appropriate extended instruction set is enabled). Spec: KhronosGroup/SPIRV-Registry#186 Signed-off-by: Sidorov, Dmitry <[email protected]>
1 parent a9f4f25 commit 7906823

9 files changed

+272
-8
lines changed

lib/SPIRV/LLVMToSPIRVDbgTran.cpp

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,14 @@ SPIRVWord adjustAccessFlags(DIScope *Scope, SPIRVWord Flags) {
481481
return Flags;
482482
}
483483

484+
// Fortran dynamic arrays can have following 'dataLocation', 'associated'
485+
// 'allocated' and 'rank' debug metadata. Such arrays are being mapped on
486+
// DebugTypeArrayDynamic from NonSemantic.Kernel.100 debug spec
487+
inline bool isFortranArrayDynamic(const DICompositeType *AT) {
488+
return (AT->getRawDataLocation() || AT->getRawAssociated() ||
489+
AT->getRawAllocated() || AT->getRawRank());
490+
}
491+
484492
/// The following methods (till the end of the file) implement translation of
485493
/// debug instrtuctions described in the spec.
486494

@@ -561,8 +569,11 @@ SPIRVEntry *LLVMToSPIRVDbgTran::transDbgQualifiedType(const DIDerivedType *QT) {
561569
}
562570

563571
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgArrayType(const DICompositeType *AT) {
564-
if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100)
572+
if (BM->getDebugInfoEIS() == SPIRVEIS_NonSemantic_Kernel_DebugInfo_100) {
573+
if (isFortranArrayDynamic(AT))
574+
return transDbgArrayTypeDynamic(AT);
565575
return transDbgArrayTypeNonSemantic(AT);
576+
}
566577

567578
return transDbgArrayTypeOpenCL(AT);
568579
}
@@ -571,8 +582,7 @@ SPIRVEntry *
571582
LLVMToSPIRVDbgTran::transDbgArrayTypeOpenCL(const DICompositeType *AT) {
572583
using namespace SPIRVDebug::Operand::TypeArray;
573584
SPIRVWordVec Ops(MinOperandCount);
574-
SPIRVEntry *Base = transDbgEntry(AT->getBaseType());
575-
Ops[BaseTypeIdx] = Base->getId();
585+
Ops[BaseTypeIdx] = transDbgEntry(AT->getBaseType())->getId();
576586

577587
DINodeArray AR(AT->getElements());
578588
// For N-dimensianal arrays AR.getNumElements() == N
@@ -615,8 +625,7 @@ SPIRVEntry *
615625
LLVMToSPIRVDbgTran::transDbgArrayTypeNonSemantic(const DICompositeType *AT) {
616626
using namespace SPIRVDebug::Operand::TypeArray;
617627
SPIRVWordVec Ops(MinOperandCount);
618-
SPIRVEntry *Base = transDbgEntry(AT->getBaseType());
619-
Ops[BaseTypeIdx] = Base->getId();
628+
Ops[BaseTypeIdx] = transDbgEntry(AT->getBaseType())->getId();
620629

621630
DINodeArray AR(AT->getElements());
622631
// For N-dimensianal arrays AR.getNumElements() == N
@@ -635,6 +644,43 @@ LLVMToSPIRVDbgTran::transDbgArrayTypeNonSemantic(const DICompositeType *AT) {
635644
return BM->addDebugInfo(SPIRVDebug::TypeArray, getVoidTy(), Ops);
636645
}
637646

647+
// The function is used to translate Fortran's dynamic arrays
648+
SPIRVEntry *
649+
LLVMToSPIRVDbgTran::transDbgArrayTypeDynamic(const DICompositeType *AT) {
650+
using namespace SPIRVDebug::Operand::TypeArrayDynamic;
651+
SPIRVWordVec Ops(MinOperandCount);
652+
Ops[BaseTypeIdx] = transDbgEntry(AT->getBaseType())->getId();
653+
654+
// DataLocation, Associated, Allocated and Rank can be either DIExpression
655+
// metadata or DIVariable
656+
auto TransOperand = [&](llvm::Metadata *DIMD) -> SPIRVWord {
657+
if (auto *DIExpr = dyn_cast_or_null<DIExpression>(DIMD))
658+
return transDbgExpression(DIExpr)->getId();
659+
if (auto *DIVar = dyn_cast_or_null<DIVariable>(DIMD)) {
660+
if (const DILocalVariable *LV = dyn_cast<DILocalVariable>(DIVar))
661+
return transDbgLocalVariable(LV)->getId();
662+
if (const DIGlobalVariable *GV = dyn_cast<DIGlobalVariable>(DIVar))
663+
return transDbgGlobalVariable(GV)->getId();
664+
}
665+
return getDebugInfoNoneId();
666+
};
667+
668+
Ops[DataLocationIdx] = TransOperand(AT->getRawDataLocation());
669+
Ops[AssociatedIdx] = TransOperand(AT->getRawAssociated());
670+
Ops[AllocatedIdx] = TransOperand(AT->getRawAllocated());
671+
Ops[RankIdx] = TransOperand(AT->getRawRank());
672+
673+
DINodeArray AR(AT->getElements());
674+
// For N-dimensianal arrays AR.getNumElements() == N
675+
const unsigned N = AR.size();
676+
Ops.resize(SubrangesIdx + N);
677+
for (unsigned I = 0; I < N; ++I) {
678+
DISubrange *SR = cast<DISubrange>(AR[I]);
679+
Ops[SubrangesIdx + I] = transDbgEntry(SR)->getId();
680+
}
681+
return BM->addDebugInfo(SPIRVDebug::TypeArrayDynamic, getVoidTy(), Ops);
682+
}
683+
638684
SPIRVEntry *LLVMToSPIRVDbgTran::transDbgSubrangeType(const DISubrange *ST) {
639685
using namespace SPIRVDebug::Operand::TypeSubrange;
640686
SPIRVWordVec Ops(OperandCount);

lib/SPIRV/LLVMToSPIRVDbgTran.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ class LLVMToSPIRVDbgTran {
107107
SPIRVEntry *transDbgArrayType(const DICompositeType *AT);
108108
SPIRVEntry *transDbgArrayTypeOpenCL(const DICompositeType *AT);
109109
SPIRVEntry *transDbgArrayTypeNonSemantic(const DICompositeType *AT);
110+
SPIRVEntry *transDbgArrayTypeDynamic(const DICompositeType *AT);
110111
SPIRVEntry *transDbgSubrangeType(const DISubrange *ST);
111112
SPIRVEntry *transDbgTypeDef(const DIDerivedType *D);
112113
SPIRVEntry *transDbgSubroutineType(const DISubroutineType *FT);

lib/SPIRV/SPIRVToLLVMDbgTran.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ SPIRVToLLVMDbgTran::transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst) {
273273
for (size_t I = SubrangesIdx; I < Ops.size(); ++I) {
274274
auto *SR = transDebugInst<DISubrange>(BM->get<SPIRVExtInst>(Ops[I]));
275275
if (auto *Count = SR->getCount().get<ConstantInt *>())
276-
TotalCount *= Count->getZExtValue() > 0 ? Count->getZExtValue() : 0;
276+
TotalCount *= Count->getSExtValue() > 0 ? Count->getSExtValue() : 0;
277277
Subscripts.push_back(SR);
278278
}
279279
}
@@ -282,6 +282,47 @@ SPIRVToLLVMDbgTran::transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst) {
282282
return Builder.createArrayType(Size, 0 /*align*/, BaseTy, SubscriptArray);
283283
}
284284

285+
DICompositeType *
286+
SPIRVToLLVMDbgTran::transTypeArrayDynamic(const SPIRVExtInst *DebugInst) {
287+
using namespace SPIRVDebug::Operand::TypeArrayDynamic;
288+
const SPIRVWordVec &Ops = DebugInst->getArguments();
289+
assert(Ops.size() >= MinOperandCount && "Invalid number of operands");
290+
DIType *BaseTy =
291+
transDebugInst<DIType>(BM->get<SPIRVExtInst>(Ops[BaseTypeIdx]));
292+
size_t TotalCount = 1;
293+
SmallVector<llvm::Metadata *, 8> Subscripts;
294+
for (size_t I = SubrangesIdx; I < Ops.size(); ++I) {
295+
auto *SR = transDebugInst<DISubrange>(BM->get<SPIRVExtInst>(Ops[I]));
296+
if (auto *Count = SR->getCount().get<ConstantInt *>())
297+
TotalCount *= Count->getSExtValue() > 0 ? Count->getSExtValue() : 0;
298+
Subscripts.push_back(SR);
299+
}
300+
DINodeArray SubscriptArray = Builder.getOrCreateArray(Subscripts);
301+
size_t Size = getDerivedSizeInBits(BaseTy) * TotalCount;
302+
303+
auto TransOperand = [&](SPIRVWord Idx) -> PointerUnion<DIExpression *,
304+
DIVariable *> {
305+
if (!getDbgInst<SPIRVDebug::DebugInfoNone>(Ops[Idx])) {
306+
if (const auto *GV = getDbgInst<SPIRVDebug::GlobalVariable>(Ops[Idx]))
307+
return transDebugInst<DIGlobalVariable>(GV);
308+
if (const auto *LV = getDbgInst<SPIRVDebug::LocalVariable>(Ops[Idx]))
309+
return transDebugInst<DILocalVariable>(LV);
310+
if (const auto *DIExpr = getDbgInst<SPIRVDebug::Expression>(Ops[Idx]))
311+
return transDebugInst<DIExpression>(DIExpr);
312+
}
313+
return nullptr;
314+
};
315+
PointerUnion<DIExpression *, DIVariable *> DataLocation =
316+
TransOperand(DataLocationIdx);
317+
PointerUnion<DIExpression *, DIVariable *> Associated =
318+
TransOperand(AssociatedIdx);
319+
PointerUnion<DIExpression *, DIVariable *> Allocated =
320+
TransOperand(AllocatedIdx);
321+
PointerUnion<DIExpression *, DIVariable *> Rank = TransOperand(RankIdx);
322+
return Builder.createArrayType(Size, 0 /*align*/, BaseTy, SubscriptArray,
323+
DataLocation, Associated, Allocated, Rank);
324+
}
325+
285326
DICompositeType *
286327
SPIRVToLLVMDbgTran::transTypeVector(const SPIRVExtInst *DebugInst) {
287328
using namespace SPIRVDebug::Operand::TypeVector;
@@ -1037,6 +1078,9 @@ MDNode *SPIRVToLLVMDbgTran::transDebugInstImpl(const SPIRVExtInst *DebugInst) {
10371078
case SPIRVDebug::Expression:
10381079
return transExpression(DebugInst);
10391080

1081+
case SPIRVDebug::TypeArrayDynamic:
1082+
return transTypeArrayDynamic(DebugInst);
1083+
10401084
default:
10411085
llvm_unreachable("Not implemented SPIR-V debug instruction!");
10421086
}

lib/SPIRV/SPIRVToLLVMDbgTran.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class SPIRVToLLVMDbgTran {
114114
DICompositeType *transTypeArray(const SPIRVExtInst *DebugInst);
115115
DICompositeType *transTypeArrayOpenCL(const SPIRVExtInst *DebugInst);
116116
DICompositeType *transTypeArrayNonSemantic(const SPIRVExtInst *DebugInst);
117+
DICompositeType *transTypeArrayDynamic(const SPIRVExtInst *DebugInst);
117118

118119
DICompositeType *transTypeVector(const SPIRVExtInst *DebugInst);
119120

lib/SPIRV/libSPIRV/SPIRV.debug.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ enum Instruction {
5252
Source = 35,
5353
ModuleINTEL = 36,
5454
InstCount = 37,
55-
TypeSubrange = 110
55+
TypeSubrange = 110,
56+
TypeArrayDynamic = 202
5657
};
5758

5859
enum Flag {
@@ -330,6 +331,18 @@ enum {
330331
};
331332
}
332333

334+
namespace TypeArrayDynamic {
335+
enum {
336+
BaseTypeIdx = 0,
337+
DataLocationIdx = 1,
338+
AssociatedIdx = 2,
339+
AllocatedIdx = 3,
340+
RankIdx = 4,
341+
SubrangesIdx = 5,
342+
MinOperandCount = 6
343+
};
344+
}
345+
333346
namespace TypeVector = TypeArray;
334347

335348
namespace TypeSubrange {

lib/SPIRV/libSPIRV/SPIRVExtInst.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ template <> inline void SPIRVMap<SPIRVDebugExtOpKind, std::string>::init() {
226226
add(SPIRVDebug::TypeBasic, "DebugTypeBasic");
227227
add(SPIRVDebug::TypePointer, "DebugTypePointer");
228228
add(SPIRVDebug::TypeArray, "DebugTypeArray");
229+
add(SPIRVDebug::TypeArrayDynamic, "DebugTypeArrayDynamic");
229230
add(SPIRVDebug::TypeVector, "DebugTypeVector");
230231
add(SPIRVDebug::TypeQualifier, "DebugTypeQualifier");
231232
add(SPIRVDebug::TypeFunction, "DebugTypeFunction");

test/DebugInfo/NonSemanticKernel100/FortranArray.ll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
77

88
; CHECK-LLVM: !DICompileUnit(language: DW_LANG_Fortran95
9-
; CHECK-LLVM: !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref))
9+
; CHECK-LLVM: !DICompositeType(tag: DW_TAG_array_type, baseType: ![[#BaseT:]], size: 32, elements: ![[#Elements:]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_constu, 0, DW_OP_or))
10+
; CHECK-LLVM: ![[#BaseT:]] = !DIBasicType(name: "INTEGER*4", size: 32, encoding: DW_ATE_signed)
11+
; CHECK-LLVM: ![[#Elements]] = !{![[#SubRange:]]}
12+
; CHECK-LLVM: ![[#SubRange]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref))
1013

1114
source_filename = "llvm-link"
1215
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
;; The test checks, that Fortran dynamic arrays are being correctly represented
2+
;; by SPIR-V debug information
3+
;; Unlike 'static' arrays dynamic can have following parameters of
4+
;; DICompositeType metadata with DW_TAG_array_type tag:
5+
;; Data Location, Associated, Allocated and Rank which can be represented
6+
;; by either DIExpression or DIVariable (both local and global).
7+
;; This test if for expression representation.
8+
;; FortranDynamicArrayVar.ll is for variable representation.
9+
10+
; RUN: llvm-as %s -o %t.bc
11+
; RUN: llvm-spirv %t.bc -spirv-text --spirv-debug-info-version=nonsemantic-kernel-100 -o - | FileCheck %s --check-prefix=CHECK-SPIRV
12+
; RUN: llvm-spirv %t.bc -o %t.spv --spirv-debug-info-version=nonsemantic-kernel-100
13+
; RUN: llvm-spirv -r -emit-opaque-pointers %t.spv -o %t.rev.bc
14+
; RUN: llvm-dis %t.rev.bc -o - | FileCheck %s --check-prefix=CHECK-LLVM
15+
16+
; CHECK-SPIRV-DAG: ExtInstImport [[#Import:]] "NonSemantic.Kernel.DebugInfo.100"
17+
; CHECK-SPIRV-DAG: String [[#BasicTName:]] "INTEGER*4"
18+
; CHECK-SPIRV-DAG: TypeInt [[#Int32T:]] 32 0
19+
; CHECK-SPIRV-DAG: Constant [[#Int32T]] [[#IntConst:]] 32
20+
; CHECK-SPIRV-DAG: TypeVoid [[#VoidT:]]
21+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgInfoNone:]] [[#Import]] DebugInfoNone
22+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#ArrayBasicT:]] [[#Import]] DebugTypeBasic [[#BasicTName]] [[#IntConst]] 4
23+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprLocation:]] [[#Import]] DebugExpression [[#]] [[#]] {{$}}
24+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprAssociated:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] [[#]] {{$}}
25+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprLowerBound:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] {{$}}
26+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprUpperBound:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] [[#]] {{$}}
27+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgExprCount:]] [[#Import]] DebugExpression [[#]] [[#]] [[#]] {{$}}
28+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgSubRangeId:]] [[#Import]] DebugTypeSubrange [[#DbgInfoNone]] [[#DbgExprLowerBound]] [[#DbgExprUpperBound]] [[#DbgExprCount]]
29+
; CHECK-SPIRV: ExtInst [[#VoidT]] [[#DbgArrayId:]] [[#Import]] DebugTypeArrayDynamic [[#ArrayBasicT]] [[#DbgExprLocation]] [[#DbgExprAssociated]] [[#DbgInfoNone]] [[#DbgInfoNone]] [[#DbgSubRangeId]]
30+
31+
; CHECK-LLVM: %[[#Array:]] = alloca
32+
; CHECK-LLVM: call void @llvm.dbg.value(metadata ptr %[[#Array]], metadata ![[#DbgLVar:]]
33+
; CHECK-LLVM: ![[#DbgLVar]] = !DILocalVariable(name: "pint", scope: ![[#]], file: ![[#]], line: [[#]], type: ![[#DbgLVarT:]])
34+
; CHECK-LLVM: ![[#DbgLVarT]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[#DbgArrayT:]], size: 64)
35+
; CHECK-LLVM: ![[#DbgArrayT]] = !DICompositeType(tag: DW_TAG_array_type, baseType: ![[#DbgArrayBaseT:]], size: 32, elements: ![[#Elements:]], dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_constu, 0, DW_OP_or))
36+
; CHECK-LLVM: ![[#DbgArrayBaseT]] = !DIBasicType(name: "INTEGER*4", size: 32, encoding: DW_ATE_signed)
37+
; CHECK-LLVM: ![[#Elements]] = !{![[#SubRange:]]}
38+
; CHECK-LLVM: ![[#SubRange]] = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref))
39+
40+
41+
; ModuleID = 'reproducer.ll'
42+
source_filename = "test.f90"
43+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
44+
target triple = "spir64"
45+
46+
%qnca = type { i32 addrspace(4)*, i64, i64, i64, i64, i64, [1 x { i64, i64, i64 }] }
47+
48+
; Function Attrs: noinline nounwind optnone
49+
define weak dso_local spir_kernel void @TEST() #0 !dbg !5 {
50+
newFuncRoot:
51+
%0 = alloca %qnca, align 8
52+
call void @llvm.dbg.value(metadata %qnca* %0, metadata !8, metadata !DIExpression()), !dbg !14
53+
ret void
54+
}
55+
56+
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
57+
declare void @llvm.dbg.value(metadata, metadata, metadata) #1
58+
59+
attributes #0 = { noinline nounwind optnone }
60+
attributes #1 = { nofree nosync nounwind readnone speculatable willreturn }
61+
62+
!llvm.module.flags = !{!0, !1}
63+
!llvm.dbg.cu = !{!2}
64+
!spirv.Source = !{!4}
65+
66+
!0 = !{i32 2, !"Debug Info Version", i32 3}
67+
!1 = !{i32 2, !"Dwarf Version", i32 4}
68+
!2 = distinct !DICompileUnit(language: DW_LANG_Fortran95, file: !3, producer: "fortran", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
69+
!3 = !DIFile(filename: "test.f90", directory: "/path/to")
70+
!4 = !{i32 4, i32 200000}
71+
!5 = distinct !DISubprogram(name: "test", linkageName: "MAIN__", scope: !3, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2)
72+
!6 = !DISubroutineType(types: !7)
73+
!7 = !{null}
74+
!8 = !DILocalVariable(name: "pint", scope: !5, file: !3, line: 3, type: !9)
75+
!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64)
76+
!10 = !DICompositeType(tag: DW_TAG_array_type, baseType: !11, elements: !12, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref, DW_OP_constu, 0, DW_OP_or))
77+
!11 = !DIBasicType(name: "INTEGER*4", size: 32, encoding: DW_ATE_signed)
78+
!12 = !{!13}
79+
!13 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 64, DW_OP_deref, DW_OP_push_object_address, DW_OP_plus_uconst, 48, DW_OP_deref, DW_OP_plus, DW_OP_constu, 1, DW_OP_minus), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 56, DW_OP_deref))
80+
!14 = !DILocation(line: 1, scope: !5)
81+

0 commit comments

Comments
 (0)