From bac7e2106fc7ed9f09694b167d2dab8a541cb3c6 Mon Sep 17 00:00:00 2001 From: peter mckinna Date: Mon, 14 Apr 2025 19:31:32 +1000 Subject: [PATCH 1/7] Add support for creating a SetType, a Subrangetype, a dynamic array type and for replacing arrays to the C inteface --- llvm/include/llvm-c/DebugInfo.h | 73 ++++++++++++++++++++++++++++++++- llvm/lib/IR/DebugInfo.cpp | 51 +++++++++++++++++++++++ 2 files changed, 123 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 991def64028da..f38271e130cff 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -686,7 +686,6 @@ LLVMMetadataRef LLVMDIBuilderCreateUnionType( LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang, const char *UniqueId, size_t UniqueIdLen); - /** * Create debugging information entry for an array. * \param Builder The DIBuilder. @@ -702,6 +701,78 @@ LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, LLVMMetadataRef *Subscripts, unsigned NumSubscripts); +/** + * Create debugging information entry for a set. + * @param Builder The DIBuilder. + * \param Scope The scope this module is imported into. + * \param Name A name that uniquely identifies this set. + * \param NameLen The length of the C string passed to \c Name. + * \param File File where the set is located. + * \param Line Line number of the declaration. + * \param SizeInBits Set size. + * \param AlignInBits Set alignment. + * @param BaseTy The base type of the set. + */ +LLVMMetadataRef LLVMDIBuilderCreateSetType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef BaseTy); + +/** + * Create a descriptor for a subrange with dynamic bounds. + * \param Builder The DIBuilder. + * \param Scope The scope this module is imported into. + * \param Name A name that uniquely identifies this set. + * \param NameLen The length of the C string passed to \c Name. + * \param LineNo Line number. + * \param File File where the subrange is located. + * \param SizeInBits Member size. + * \param AlignInBits Member alignment. + * \param Flags Flags. + * \param BaseTy The base type of the subrange. eg integer or enumeration + * \param LowerBound Lower bound of the subrange. + * \param UpperBound Upper bound of the subrange. + * \param Stride Stride of the subrange. + * \param Bias Bias of the subrange. + */ +LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, + uint64_t SizeInBits, uint32_t AlignInBits, + LLVMDIFlags Flags, LLVMMetadataRef BaseTy, + LLVMMetadataRef LowerBound, LLVMMetadataRef UpperBound, + LLVMMetadataRef Stride, LLVMMetadataRef Bias); + +/** + * Create debugging information entry for a dynamic array. + * \param Builder The DIBuilder. + * \param Size Array size. + * \param AlignInBits Alignment. + * \param Ty Element type. + * \param Subscripts Subscripts. + * \param NumSubscripts Number of subscripts. + * \param DataLocation DataLocation. + * \param Associated Associated. + * \param Allocated Allocated. + * \param Rank Rank. + * \param BitStride BitStride. + */ +LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, + uint64_t Size, uint32_t AlignInBits, + LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, unsigned NumSubscripts, + LLVMMetadataRef DataLocation, LLVMMetadataRef Associated, + LLVMMetadataRef Allocated, LLVMMetadataRef Rank, LLVMMetadataRef BitStride); + +/** + * Replace arrays. + * + * @see DIBuilder::replaceArrays() + */ +void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T, + LLVMMetadataRef *Elements, unsigned NumElements); + /** * Create debugging information entry for a vector type. * \param Builder The DIBuilder. diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index dff9a08c2c8e0..617ae3682370f 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1321,6 +1321,57 @@ return wrap(unwrap(Builder)->createEnumerationType( LineNumber, SizeInBits, AlignInBits, Elts, unwrapDI(ClassTy))); } +LLVMMetadataRef LLVMDIBuilderCreateSetType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, + uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef BaseTy) { + return wrap(unwrap(Builder)->createSetType( + unwrapDI(Scope), {Name, NameLen}, unwrapDI(File), + LineNumber, SizeInBits, AlignInBits, unwrapDI(BaseTy))); +} + +LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, + uint64_t SizeInBits, uint32_t AlignInBits, + LLVMDIFlags Flags, LLVMMetadataRef BaseTy, + LLVMMetadataRef LowerBound, LLVMMetadataRef UpperBound, + LLVMMetadataRef Stride, LLVMMetadataRef Bias + ) { + return wrap(unwrap(Builder)->createSubrangeType( + {Name, NameLen}, unwrapDI(File), LineNo, + unwrapDI(Scope), SizeInBits, AlignInBits, + map_from_llvmDIFlags(Flags), unwrapDI(BaseTy), + unwrap(LowerBound), unwrap(UpperBound), + unwrap(Stride), unwrap(Bias))); +} + +LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( + LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, + uint64_t Size, uint32_t AlignInBits, + LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, unsigned NumSubscripts, + LLVMMetadataRef DataLocation, LLVMMetadataRef Associated, + LLVMMetadataRef Allocated, LLVMMetadataRef Rank, LLVMMetadataRef BitStride) { + auto Subs = + unwrap(Builder)->getOrCreateArray({unwrap(Subscripts), NumSubscripts}); + return wrap(unwrap(Builder)->createArrayType( + unwrapDI(Scope), + {Name, NameLen}, unwrapDI(File), LineNo, + Size, AlignInBits, unwrapDI(Ty), Subs, + unwrap(DataLocation), unwrap(Associated), + unwrap(Allocated), unwrap(Rank), + unwrap(BitStride))); +} + +void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T, + LLVMMetadataRef *Elements, unsigned NumElements) { + auto Arr = unwrap(*T); + auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements), + NumElements}); + unwrap(Builder)->replaceArrays(Arr, Elts); +} + LLVMMetadataRef LLVMDIBuilderCreateUnionType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, LLVMMetadataRef File, unsigned LineNumber, From f362824ca5ebbc5953323d985f71fe752124a189 Mon Sep 17 00:00:00 2001 From: peter mckinna Date: Mon, 14 Apr 2025 19:31:32 +1000 Subject: [PATCH 2/7] Add support for creating a SetType, a Subrangetype, a dynamic array type and for replacing arrays to the C inteface --- llvm/include/llvm-c/DebugInfo.h | 25 ++-- llvm/lib/IR/DebugInfo.cpp | 35 +++-- .../Bindings/llvm-c/debug_info_new_format.ll | 122 +++++++++--------- llvm/tools/llvm-c-test/debuginfo.c | 36 ++++++ 4 files changed, 127 insertions(+), 91 deletions(-) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index f38271e130cff..3c68282875dd7 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -703,15 +703,15 @@ LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size, /** * Create debugging information entry for a set. - * @param Builder The DIBuilder. - * \param Scope The scope this module is imported into. + * \param Builder The DIBuilder. + * \param Scope The scope in which the set is defined. * \param Name A name that uniquely identifies this set. * \param NameLen The length of the C string passed to \c Name. * \param File File where the set is located. * \param Line Line number of the declaration. * \param SizeInBits Set size. * \param AlignInBits Set alignment. - * @param BaseTy The base type of the set. + * \param BaseTy The base type of the set. */ LLVMMetadataRef LLVMDIBuilderCreateSetType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, @@ -721,8 +721,8 @@ LLVMMetadataRef LLVMDIBuilderCreateSetType( /** * Create a descriptor for a subrange with dynamic bounds. * \param Builder The DIBuilder. - * \param Scope The scope this module is imported into. - * \param Name A name that uniquely identifies this set. + * \param Scope The scope in which the subrange is defined. + * \param Name A name that uniquely identifies this subrange. * \param NameLen The length of the C string passed to \c Name. * \param LineNo Line number. * \param File File where the subrange is located. @@ -737,9 +737,8 @@ LLVMMetadataRef LLVMDIBuilderCreateSetType( */ LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, unsigned LineNo, LLVMMetadataRef File, - uint64_t SizeInBits, uint32_t AlignInBits, - LLVMDIFlags Flags, LLVMMetadataRef BaseTy, + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t SizeInBits, + uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef BaseTy, LLVMMetadataRef LowerBound, LLVMMetadataRef UpperBound, LLVMMetadataRef Stride, LLVMMetadataRef Bias); @@ -759,11 +758,11 @@ LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( */ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, unsigned LineNo, LLVMMetadataRef File, - uint64_t Size, uint32_t AlignInBits, - LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, unsigned NumSubscripts, - LLVMMetadataRef DataLocation, LLVMMetadataRef Associated, - LLVMMetadataRef Allocated, LLVMMetadataRef Rank, LLVMMetadataRef BitStride); + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t Size, + uint32_t AlignInBits, LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, + unsigned NumSubscripts, LLVMMetadataRef DataLocation, + LLVMMetadataRef Associated, LLVMMetadataRef Allocated, LLVMMetadataRef Rank, + LLVMMetadataRef BitStride); /** * Replace arrays. diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 617ae3682370f..9b1277f4f397b 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1332,32 +1332,29 @@ LLVMMetadataRef LLVMDIBuilderCreateSetType( LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, unsigned LineNo, LLVMMetadataRef File, - uint64_t SizeInBits, uint32_t AlignInBits, - LLVMDIFlags Flags, LLVMMetadataRef BaseTy, + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t SizeInBits, + uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef BaseTy, LLVMMetadataRef LowerBound, LLVMMetadataRef UpperBound, - LLVMMetadataRef Stride, LLVMMetadataRef Bias - ) { + LLVMMetadataRef Stride, LLVMMetadataRef Bias) { return wrap(unwrap(Builder)->createSubrangeType( - {Name, NameLen}, unwrapDI(File), LineNo, - unwrapDI(Scope), SizeInBits, AlignInBits, - map_from_llvmDIFlags(Flags), unwrapDI(BaseTy), - unwrap(LowerBound), unwrap(UpperBound), - unwrap(Stride), unwrap(Bias))); + {Name, NameLen}, unwrapDI(File), LineNo, unwrapDI(Scope), + SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags), + unwrapDI(BaseTy), unwrap(LowerBound), + unwrap(UpperBound), unwrap(Stride), + unwrap(Bias))); } LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, - size_t NameLen, unsigned LineNo, LLVMMetadataRef File, - uint64_t Size, uint32_t AlignInBits, - LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, unsigned NumSubscripts, - LLVMMetadataRef DataLocation, LLVMMetadataRef Associated, - LLVMMetadataRef Allocated, LLVMMetadataRef Rank, LLVMMetadataRef BitStride) { + size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t Size, + uint32_t AlignInBits, LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts, + unsigned NumSubscripts, LLVMMetadataRef DataLocation, + LLVMMetadataRef Associated, LLVMMetadataRef Allocated, LLVMMetadataRef Rank, + LLVMMetadataRef BitStride) { auto Subs = unwrap(Builder)->getOrCreateArray({unwrap(Subscripts), NumSubscripts}); return wrap(unwrap(Builder)->createArrayType( - unwrapDI(Scope), - {Name, NameLen}, unwrapDI(File), LineNo, + unwrapDI(Scope), {Name, NameLen}, unwrapDI(File), LineNo, Size, AlignInBits, unwrapDI(Ty), Subs, unwrap(DataLocation), unwrap(Associated), unwrap(Allocated), unwrap(Rank), @@ -1367,8 +1364,8 @@ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T, LLVMMetadataRef *Elements, unsigned NumElements) { auto Arr = unwrap(*T); - auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements), - NumElements}); + auto Elts = + unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements}); unwrap(Builder)->replaceArrays(Arr, Elts); } diff --git a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll index 86ec915bd03ba..a44817e020148 100644 --- a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll +++ b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll @@ -3,33 +3,36 @@ ; CHECK: ; ModuleID = 'debuginfo.c' ; CHECK-NEXT: source_filename = "debuginfo.c" - -; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !36 { + +; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !39 { ; CHECK-NEXT: entry: -; CHECK-NEXT: #dbg_declare(i64 0, !43, !DIExpression(), !50) -; CHECK-NEXT: #dbg_declare(i64 0, !44, !DIExpression(), !50) -; CHECK-NEXT: #dbg_declare(i64 0, !45, !DIExpression(), !50) -; CHECK-NEXT: #dbg_label(!51, !50) +; CHECK-NEXT: #dbg_declare(i64 0, !44, !DIExpression(), !51) +; CHECK-NEXT: #dbg_declare(i64 0, !45, !DIExpression(), !51) +; CHECK-NEXT: #dbg_declare(i64 0, !46, !DIExpression(), !51) +; CHECK-NEXT: #dbg_label(!52, !51) ; CHECK-NEXT: br label %vars -; CHECK-NEXT: #dbg_label(!52, !50) +; CHECK-NEXT: #dbg_label(!53, !51) ; CHECK-NEXT: br label %vars -; CHECK: vars: +; CHECK: vars: ; preds = %entry, %entry ; CHECK-NEXT: %p1 = phi i64 [ 0, %entry ] ; CHECK-NEXT: %p2 = phi i64 [ 0, %entry ] -; CHECK-NEXT: #dbg_value(i64 0, !46, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !53) -; CHECK-NEXT: #dbg_value(i64 1, !48, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !53) +; CHECK-NEXT: #dbg_value(i64 0, !47, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !54) +; CHECK-NEXT: #dbg_value(i64 1, !49, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !54) ; CHECK-NEXT: %a = add i64 %p1, %p2 ; CHECK-NEXT: ret i64 0 ; CHECK-NEXT: } - + ; CHECK: !llvm.dbg.cu = !{!0} -; CHECK-NEXT: !FooType = !{!33} +; CHECK-NEXT: !FooType = !{!28} ; CHECK-NEXT: !EnumTest = !{!3} -; CHECK-NEXT: !LargeEnumTest = !{!11} - -; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !16, imports: !24, macros: !28, splitDebugInlining: false, sysroot: "/") +; CHECK-NEXT: !SubrangeType = !{!33} +; CHECK-NEXT: !SetType1 = !{!34} +; CHECK-NEXT: !SetType2 = !{!35} +; CHECK-NEXT: !DynType = !{!36} + +; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !11, imports: !19, macros: !23, splitDebugInlining: false, sysroot: "/") ; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c", directory: ".") -; CHECK-NEXT: !2 = !{!3, !11} +; CHECK-NEXT: !2 = !{!3} ; CHECK-NEXT: !3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EnumTest", scope: !4, file: !1, baseType: !6, size: 64, elements: !7) ; CHECK-NEXT: !4 = !DINamespace(name: "NameSpace", scope: !5) ; CHECK-NEXT: !5 = !DIModule(scope: null, name: "llvm-c-test", includePath: "/test/include/llvm-c-test.h") @@ -38,46 +41,47 @@ ; CHECK-NEXT: !8 = !DIEnumerator(name: "Test_A", value: 0, isUnsigned: true) ; CHECK-NEXT: !9 = !DIEnumerator(name: "Test_B", value: 1, isUnsigned: true) ; CHECK-NEXT: !10 = !DIEnumerator(name: "Test_B", value: 2, isUnsigned: true) -; CHECK-NEXT: !11 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "LargeEnumTest", scope: !4, file: !1, baseType: !12, size: 128, elements: !13) -; CHECK-NEXT: !12 = !DIBasicType(name: "UInt128", size: 128) -; CHECK-NEXT: !13 = !{!14, !15} -; CHECK-NEXT: !14 = !DIEnumerator(name: "Test_D", value: 100000000000000000000000000000000000000) -; CHECK-NEXT: !15 = !DIEnumerator(name: "Test_E", value: -1) -; CHECK-NEXT: !16 = !{!17, !21} -; CHECK-NEXT: !17 = !DIGlobalVariableExpression(var: !18, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) -; CHECK-NEXT: !18 = distinct !DIGlobalVariable(name: "globalClass", scope: !5, file: !1, line: 1, type: !19, isLocal: true, isDefinition: true) -; CHECK-NEXT: !19 = !DICompositeType(tag: DW_TAG_structure_type, name: "TestClass", scope: !1, file: !1, line: 42, size: 64, flags: DIFlagObjcClassComplete, elements: !20) -; CHECK-NEXT: !20 = !{} -; CHECK-NEXT: !21 = !DIGlobalVariableExpression(var: !22, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) -; CHECK-NEXT: !22 = distinct !DIGlobalVariable(name: "global", scope: !5, file: !1, line: 1, type: !23, isLocal: true, isDefinition: true) -; CHECK-NEXT: !23 = !DIDerivedType(tag: DW_TAG_typedef, name: "int64_t", scope: !1, file: !1, line: 42, baseType: !6) -; CHECK-NEXT: !24 = !{!25, !27} -; CHECK-NEXT: !25 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !26, file: !1, line: 42) -; CHECK-NEXT: !26 = !DIModule(scope: null, name: "llvm-c-test-import", includePath: "/test/include/llvm-c-test-import.h") -; CHECK-NEXT: !27 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !25, file: !1, line: 42) -; CHECK-NEXT: !28 = !{!29} -; CHECK-NEXT: !29 = !DIMacroFile(file: !1, nodes: !30) -; CHECK-NEXT: !30 = !{!31, !32} -; CHECK-NEXT: !31 = !DIMacro(type: DW_MACINFO_define, name: "SIMPLE_DEFINE") -; CHECK-NEXT: !32 = !DIMacro(type: DW_MACINFO_define, name: "VALUE_DEFINE", value: "1") -; CHECK-NEXT: !33 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !34, size: 192, dwarfAddressSpace: 0) -; CHECK-NEXT: !34 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !4, file: !1, size: 192, elements: !35, runtimeLang: DW_LANG_C89, identifier: "MyStruct") -; CHECK-NEXT: !35 = !{!6, !6, !6} -; CHECK-NEXT: !36 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !37, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !42) -; CHECK-NEXT: !37 = !DISubroutineType(types: !38) -; CHECK-NEXT: !38 = !{!6, !6, !39} -; CHECK-NEXT: !39 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !40) -; CHECK-NEXT: !40 = !{!41} -; CHECK-NEXT: !41 = !DISubrange(count: 10, lowerBound: 0) -; CHECK-NEXT: !42 = !{!43, !44, !45, !46, !48, !49} -; CHECK-NEXT: !43 = !DILocalVariable(name: "a", arg: 1, scope: !36, file: !1, line: 42, type: !6) -; CHECK-NEXT: !44 = !DILocalVariable(name: "b", arg: 2, scope: !36, file: !1, line: 42, type: !6) -; CHECK-NEXT: !45 = !DILocalVariable(name: "c", arg: 3, scope: !36, file: !1, line: 42, type: !39) -; CHECK-NEXT: !46 = !DILocalVariable(name: "d", scope: !47, file: !1, line: 43, type: !6) -; CHECK-NEXT: !47 = distinct !DILexicalBlock(scope: !36, file: !1, line: 42) -; CHECK-NEXT: !48 = !DILocalVariable(name: "e", scope: !47, file: !1, line: 44, type: !6) -; CHECK-NEXT: !49 = !DILabel(scope: !36, name: "label3", file: !1, line: 42) -; CHECK-NEXT: !50 = !DILocation(line: 42, scope: !36) -; CHECK-NEXT: !51 = !DILabel(scope: !36, name: "label1", file: !1, line: 42) -; CHECK-NEXT: !52 = !DILabel(scope: !36, name: "label2", file: !1, line: 42) -; CHECK-NEXT: !53 = !DILocation(line: 43, scope: !36) +; CHECK-NEXT: !11 = !{!12, !16} +; CHECK-NEXT: !12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) +; CHECK-NEXT: !13 = distinct !DIGlobalVariable(name: "globalClass", scope: !5, file: !1, line: 1, type: !14, isLocal: true, isDefinition: true) +; CHECK-NEXT: !14 = !DICompositeType(tag: DW_TAG_structure_type, name: "TestClass", scope: !1, file: !1, line: 42, size: 64, flags: DIFlagObjcClassComplete, elements: !15) +; CHECK-NEXT: !15 = !{} +; CHECK-NEXT: !16 = !DIGlobalVariableExpression(var: !17, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) +; CHECK-NEXT: !17 = distinct !DIGlobalVariable(name: "global", scope: !5, file: !1, line: 1, type: !18, isLocal: true, isDefinition: true) +; CHECK-NEXT: !18 = !DIDerivedType(tag: DW_TAG_typedef, name: "int64_t", scope: !1, file: !1, line: 42, baseType: !6) +; CHECK-NEXT: !19 = !{!20, !22} +; CHECK-NEXT: !20 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !21, file: !1, line: 42) +; CHECK-NEXT: !21 = !DIModule(scope: null, name: "llvm-c-test-import", includePath: "/test/include/llvm-c-test-import.h") +; CHECK-NEXT: !22 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !20, file: !1, line: 42) +; CHECK-NEXT: !23 = !{!24} +; CHECK-NEXT: !24 = !DIMacroFile(file: !1, nodes: !25) +; CHECK-NEXT: !25 = !{!26, !27} +; CHECK-NEXT: !26 = !DIMacro(type: DW_MACINFO_define, name: "SIMPLE_DEFINE") +; CHECK-NEXT: !27 = !DIMacro(type: DW_MACINFO_define, name: "VALUE_DEFINE", value: "1") +; CHECK-NEXT: !28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 192, dwarfAddressSpace: 0) +; CHECK-NEXT: !29 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !4, file: !1, size: 192, elements: !30, runtimeLang: DW_LANG_C89, identifier: "MyStruct") +; CHECK-NEXT: !30 = !{!31} +; CHECK-NEXT: !31 = !DICompositeType(tag: DW_TAG_structure_type, name: "ThisStruc", scope: !4, file: !1, size: 192, elements: !32, runtimeLang: DW_LANG_C89, identifier: "ThisStruc") +; CHECK-NEXT: !32 = !{!6, !6, !6} +; CHECK-NEXT: !33 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1) +; CHECK-NEXT: !34 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64) +; CHECK-NEXT: !35 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !33, size: 64) +; CHECK-NEXT: !36 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !37, dataLocation: !DIExpression()) +; CHECK-NEXT: !37 = !{!38} +; CHECK-NEXT: !38 = !DISubrange(count: 10, lowerBound: 0) +; CHECK-NEXT: !39 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !40, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !43) +; CHECK-NEXT: !40 = !DISubroutineType(types: !41) +; CHECK-NEXT: !41 = !{!6, !6, !42} +; CHECK-NEXT: !42 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !37) +; CHECK-NEXT: !43 = !{!44, !45, !46, !47, !49, !50} +; CHECK-NEXT: !44 = !DILocalVariable(name: "a", arg: 1, scope: !39, file: !1, line: 42, type: !6) +; CHECK-NEXT: !45 = !DILocalVariable(name: "b", arg: 2, scope: !39, file: !1, line: 42, type: !6) +; CHECK-NEXT: !46 = !DILocalVariable(name: "c", arg: 3, scope: !39, file: !1, line: 42, type: !42) +; CHECK-NEXT: !47 = !DILocalVariable(name: "d", scope: !48, file: !1, line: 43, type: !6) +; CHECK-NEXT: !48 = distinct !DILexicalBlock(scope: !39, file: !1, line: 42) +; CHECK-NEXT: !49 = !DILocalVariable(name: "e", scope: !48, file: !1, line: 44, type: !6) +; CHECK-NEXT: !50 = !DILabel(scope: !39, name: "label3", file: !1, line: 42) +; CHECK-NEXT: !51 = !DILocation(line: 42, scope: !39) +; CHECK-NEXT: !52 = !DILabel(scope: !39, name: "label1", file: !1, line: 42) +; CHECK-NEXT: !53 = !DILabel(scope: !39, name: "label2", file: !1, line: 42) +; CHECK-NEXT: !54 = !DILocation(line: 43, scope: !39) diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c index 3ac5a6bc2cf03..694c206d467c9 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -235,6 +235,42 @@ int llvm_test_dibuilder(void) { M, "LargeEnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), LargeEnumTest)); + LLVMMetadataRef lo = LLVMValueAsMetadata(FooVal1); + LLVMMetadataRef hi = LLVMValueAsMetadata(FooVal2); + LLVMMetadataRef SubrangeMetadataTy = LLVMDIBuilderCreateSubrangeType( + DIB, File, "foo", 3, 42, File, 64, 0, 0, Int64Ty, lo, hi, NULL, NULL); + LLVMAddNamedMetadataOperand( + M, "SubrangeType", + LLVMMetadataAsValue(LLVMGetModuleContext(M), SubrangeMetadataTy)); + + LLVMMetadataRef SetMetadataTy1 = LLVMDIBuilderCreateSetType( + DIB, File, "enumset", 7, File, 42, 64, 0, EnumTest); + LLVMMetadataRef SetMetadataTy2 = LLVMDIBuilderCreateSetType( + DIB, File, "subrangeset", 11, File, 42, 64, 0, SubrangeMetadataTy); + LLVMAddNamedMetadataOperand( + M, "SetType1", + LLVMMetadataAsValue(LLVMGetModuleContext(M), SetMetadataTy1)); + LLVMAddNamedMetadataOperand( + M, "SetType2", + LLVMMetadataAsValue(LLVMGetModuleContext(M), SetMetadataTy2)); + + LLVMMetadataRef DynSubscripts[] = { + LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10), + }; + LLVMMetadataRef LocExpression = LLVMDIBuilderCreateExpression(DIB, NULL, 0); + LLVMMetadataRef DynamicArrayMetadataTy = LLVMDIBuilderCreateDynamicArrayType( + DIB, File, "foo", 3, 42, File, 64 * 10, 0, Int64Ty, DynSubscripts, 1, + LocExpression, NULL, NULL, NULL, NULL); + LLVMAddNamedMetadataOperand( + M, "DynType", + LLVMMetadataAsValue(LLVMGetModuleContext(M), DynamicArrayMetadataTy)); + + LLVMMetadataRef StructElts[] = {Int64Ty, Int64Ty, Int64Ty}; + LLVMMetadataRef StructDestTy = LLVMDIBuilderCreateStructType( + DIB, NameSpace, "ThisStruct", 9, File, 0, 192, 0, 0, NULL, StructElts, 3, + LLVMDWARFSourceLanguageC, NULL, "ThisStruct", 9); + LLVMReplaceArrays(DIB, &StructDbgTy, &StructDestTy, 1); + // Using the new debug format, debug records get attached to instructions. // Insert a `br` and `ret` now to absorb the debug records which are // currently "trailing", meaning that they're associated with a block From 092e83d9b56ae5c6025f86f449e5b81cb2f480c9 Mon Sep 17 00:00:00 2001 From: peter mckinna Date: Wed, 7 May 2025 09:43:28 +1000 Subject: [PATCH 3/7] Amend testcase after merge --- .../Bindings/llvm-c/debug_info_new_format.ll | 125 +++++++++--------- 1 file changed, 66 insertions(+), 59 deletions(-) diff --git a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll index a44817e020148..91ffd05cc0bbc 100644 --- a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll +++ b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll @@ -4,35 +4,37 @@ ; CHECK: ; ModuleID = 'debuginfo.c' ; CHECK-NEXT: source_filename = "debuginfo.c" -; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !39 { +; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !44 { ; CHECK-NEXT: entry: -; CHECK-NEXT: #dbg_declare(i64 0, !44, !DIExpression(), !51) -; CHECK-NEXT: #dbg_declare(i64 0, !45, !DIExpression(), !51) -; CHECK-NEXT: #dbg_declare(i64 0, !46, !DIExpression(), !51) -; CHECK-NEXT: #dbg_label(!52, !51) +; CHECK-NEXT: #dbg_declare(i64 0, !49, !DIExpression(), !56) +; CHECK-NEXT: #dbg_declare(i64 0, !50, !DIExpression(), !56) +; CHECK-NEXT: #dbg_declare(i64 0, !51, !DIExpression(), !56) +; CHECK-NEXT: #dbg_label(!57, !56) ; CHECK-NEXT: br label %vars -; CHECK-NEXT: #dbg_label(!53, !51) +; CHECK-NEXT: #dbg_label(!58, !56) ; CHECK-NEXT: br label %vars + ; CHECK: vars: ; preds = %entry, %entry ; CHECK-NEXT: %p1 = phi i64 [ 0, %entry ] ; CHECK-NEXT: %p2 = phi i64 [ 0, %entry ] -; CHECK-NEXT: #dbg_value(i64 0, !47, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !54) -; CHECK-NEXT: #dbg_value(i64 1, !49, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !54) +; CHECK-NEXT: #dbg_value(i64 0, !52, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !59) +; CHECK-NEXT: #dbg_value(i64 1, !54, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !59) ; CHECK-NEXT: %a = add i64 %p1, %p2 ; CHECK-NEXT: ret i64 0 ; CHECK-NEXT: } ; CHECK: !llvm.dbg.cu = !{!0} -; CHECK-NEXT: !FooType = !{!28} +; CHECK-NEXT: !FooType = !{!33} ; CHECK-NEXT: !EnumTest = !{!3} -; CHECK-NEXT: !SubrangeType = !{!33} -; CHECK-NEXT: !SetType1 = !{!34} -; CHECK-NEXT: !SetType2 = !{!35} -; CHECK-NEXT: !DynType = !{!36} +; CHECK-NEXT: !LargeEnumTest = !{!11} +; CHECK-NEXT: !SubrangeType = !{!38} +; CHECK-NEXT: !SetType1 = !{!39} +; CHECK-NEXT: !SetType2 = !{!40} +; CHECK-NEXT: !DynType = !{!41} -; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !11, imports: !19, macros: !23, splitDebugInlining: false, sysroot: "/") +; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !16, imports: !24, macros: !28, splitDebugInlining: false, sysroot: "/") ; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c", directory: ".") -; CHECK-NEXT: !2 = !{!3} +; CHECK-NEXT: !2 = !{!3, !11} ; CHECK-NEXT: !3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EnumTest", scope: !4, file: !1, baseType: !6, size: 64, elements: !7) ; CHECK-NEXT: !4 = !DINamespace(name: "NameSpace", scope: !5) ; CHECK-NEXT: !5 = !DIModule(scope: null, name: "llvm-c-test", includePath: "/test/include/llvm-c-test.h") @@ -41,47 +43,52 @@ ; CHECK-NEXT: !8 = !DIEnumerator(name: "Test_A", value: 0, isUnsigned: true) ; CHECK-NEXT: !9 = !DIEnumerator(name: "Test_B", value: 1, isUnsigned: true) ; CHECK-NEXT: !10 = !DIEnumerator(name: "Test_B", value: 2, isUnsigned: true) -; CHECK-NEXT: !11 = !{!12, !16} -; CHECK-NEXT: !12 = !DIGlobalVariableExpression(var: !13, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) -; CHECK-NEXT: !13 = distinct !DIGlobalVariable(name: "globalClass", scope: !5, file: !1, line: 1, type: !14, isLocal: true, isDefinition: true) -; CHECK-NEXT: !14 = !DICompositeType(tag: DW_TAG_structure_type, name: "TestClass", scope: !1, file: !1, line: 42, size: 64, flags: DIFlagObjcClassComplete, elements: !15) -; CHECK-NEXT: !15 = !{} -; CHECK-NEXT: !16 = !DIGlobalVariableExpression(var: !17, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) -; CHECK-NEXT: !17 = distinct !DIGlobalVariable(name: "global", scope: !5, file: !1, line: 1, type: !18, isLocal: true, isDefinition: true) -; CHECK-NEXT: !18 = !DIDerivedType(tag: DW_TAG_typedef, name: "int64_t", scope: !1, file: !1, line: 42, baseType: !6) -; CHECK-NEXT: !19 = !{!20, !22} -; CHECK-NEXT: !20 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !21, file: !1, line: 42) -; CHECK-NEXT: !21 = !DIModule(scope: null, name: "llvm-c-test-import", includePath: "/test/include/llvm-c-test-import.h") -; CHECK-NEXT: !22 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !20, file: !1, line: 42) -; CHECK-NEXT: !23 = !{!24} -; CHECK-NEXT: !24 = !DIMacroFile(file: !1, nodes: !25) -; CHECK-NEXT: !25 = !{!26, !27} -; CHECK-NEXT: !26 = !DIMacro(type: DW_MACINFO_define, name: "SIMPLE_DEFINE") -; CHECK-NEXT: !27 = !DIMacro(type: DW_MACINFO_define, name: "VALUE_DEFINE", value: "1") -; CHECK-NEXT: !28 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !29, size: 192, dwarfAddressSpace: 0) -; CHECK-NEXT: !29 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !4, file: !1, size: 192, elements: !30, runtimeLang: DW_LANG_C89, identifier: "MyStruct") -; CHECK-NEXT: !30 = !{!31} -; CHECK-NEXT: !31 = !DICompositeType(tag: DW_TAG_structure_type, name: "ThisStruc", scope: !4, file: !1, size: 192, elements: !32, runtimeLang: DW_LANG_C89, identifier: "ThisStruc") -; CHECK-NEXT: !32 = !{!6, !6, !6} -; CHECK-NEXT: !33 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1) -; CHECK-NEXT: !34 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64) -; CHECK-NEXT: !35 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !33, size: 64) -; CHECK-NEXT: !36 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !37, dataLocation: !DIExpression()) -; CHECK-NEXT: !37 = !{!38} -; CHECK-NEXT: !38 = !DISubrange(count: 10, lowerBound: 0) -; CHECK-NEXT: !39 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !40, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !43) -; CHECK-NEXT: !40 = !DISubroutineType(types: !41) -; CHECK-NEXT: !41 = !{!6, !6, !42} -; CHECK-NEXT: !42 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !37) -; CHECK-NEXT: !43 = !{!44, !45, !46, !47, !49, !50} -; CHECK-NEXT: !44 = !DILocalVariable(name: "a", arg: 1, scope: !39, file: !1, line: 42, type: !6) -; CHECK-NEXT: !45 = !DILocalVariable(name: "b", arg: 2, scope: !39, file: !1, line: 42, type: !6) -; CHECK-NEXT: !46 = !DILocalVariable(name: "c", arg: 3, scope: !39, file: !1, line: 42, type: !42) -; CHECK-NEXT: !47 = !DILocalVariable(name: "d", scope: !48, file: !1, line: 43, type: !6) -; CHECK-NEXT: !48 = distinct !DILexicalBlock(scope: !39, file: !1, line: 42) -; CHECK-NEXT: !49 = !DILocalVariable(name: "e", scope: !48, file: !1, line: 44, type: !6) -; CHECK-NEXT: !50 = !DILabel(scope: !39, name: "label3", file: !1, line: 42) -; CHECK-NEXT: !51 = !DILocation(line: 42, scope: !39) -; CHECK-NEXT: !52 = !DILabel(scope: !39, name: "label1", file: !1, line: 42) -; CHECK-NEXT: !53 = !DILabel(scope: !39, name: "label2", file: !1, line: 42) -; CHECK-NEXT: !54 = !DILocation(line: 43, scope: !39) +; CHECK-NEXT: !11 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "LargeEnumTest", scope: !4, file: !1, baseType: !12, size: 128, elements: !13) +; CHECK-NEXT: !12 = !DIBasicType(name: "UInt128", size: 128) +; CHECK-NEXT: !13 = !{!14, !15} +; CHECK-NEXT: !14 = !DIEnumerator(name: "Test_D", value: 100000000000000000000000000000000000000) +; CHECK-NEXT: !15 = !DIEnumerator(name: "Test_E", value: -1) +; CHECK-NEXT: !16 = !{!17, !21} +; CHECK-NEXT: !17 = !DIGlobalVariableExpression(var: !18, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) +; CHECK-NEXT: !18 = distinct !DIGlobalVariable(name: "globalClass", scope: !5, file: !1, line: 1, type: !19, isLocal: true, isDefinition: true) +; CHECK-NEXT: !19 = !DICompositeType(tag: DW_TAG_structure_type, name: "TestClass", scope: !1, file: !1, line: 42, size: 64, flags: DIFlagObjcClassComplete, elements: !20) +; CHECK-NEXT: !20 = !{} +; CHECK-NEXT: !21 = !DIGlobalVariableExpression(var: !22, expr: !DIExpression(DW_OP_constu, 0, DW_OP_stack_value)) +; CHECK-NEXT: !22 = distinct !DIGlobalVariable(name: "global", scope: !5, file: !1, line: 1, type: !23, isLocal: true, isDefinition: true) +; CHECK-NEXT: !23 = !DIDerivedType(tag: DW_TAG_typedef, name: "int64_t", scope: !1, file: !1, line: 42, baseType: !6) +; CHECK-NEXT: !24 = !{!25, !27} +; CHECK-NEXT: !25 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !26, file: !1, line: 42) +; CHECK-NEXT: !26 = !DIModule(scope: null, name: "llvm-c-test-import", includePath: "/test/include/llvm-c-test-import.h") +; CHECK-NEXT: !27 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !5, entity: !25, file: !1, line: 42) +; CHECK-NEXT: !28 = !{!29} +; CHECK-NEXT: !29 = !DIMacroFile(file: !1, nodes: !30) +; CHECK-NEXT: !30 = !{!31, !32} +; CHECK-NEXT: !31 = !DIMacro(type: DW_MACINFO_define, name: "SIMPLE_DEFINE") +; CHECK-NEXT: !32 = !DIMacro(type: DW_MACINFO_define, name: "VALUE_DEFINE", value: "1") +; CHECK-NEXT: !33 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !34, size: 192, dwarfAddressSpace: 0) +; CHECK-NEXT: !34 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !4, file: !1, size: 192, elements: !35, runtimeLang: DW_LANG_C89, identifier: "MyStruct") +; CHECK-NEXT: !35 = !{!36} +; CHECK-NEXT: !36 = !DICompositeType(tag: DW_TAG_structure_type, name: "ThisStruc", scope: !4, file: !1, size: 192, elements: !37, runtimeLang: DW_LANG_C89, identifier: "ThisStruc") +; CHECK-NEXT: !37 = !{!6, !6, !6} +; CHECK-NEXT: !38 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1) +; CHECK-NEXT: !39 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64) +; CHECK-NEXT: !40 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !38, size: 64) +; CHECK-NEXT: !41 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !42, dataLocation: !DIExpression()) +; CHECK-NEXT: !42 = !{!43} +; CHECK-NEXT: !43 = !DISubrange(count: 10, lowerBound: 0) +; CHECK-NEXT: !44 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !45, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !48) +; CHECK-NEXT: !45 = !DISubroutineType(types: !46) +; CHECK-NEXT: !46 = !{!6, !6, !47} +; CHECK-NEXT: !47 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !42) +; CHECK-NEXT: !48 = !{!49, !50, !51, !52, !54, !55} +; CHECK-NEXT: !49 = !DILocalVariable(name: "a", arg: 1, scope: !44, file: !1, line: 42, type: !6) +; CHECK-NEXT: !50 = !DILocalVariable(name: "b", arg: 2, scope: !44, file: !1, line: 42, type: !6) +; CHECK-NEXT: !51 = !DILocalVariable(name: "c", arg: 3, scope: !44, file: !1, line: 42, type: !47) +; CHECK-NEXT: !52 = !DILocalVariable(name: "d", scope: !53, file: !1, line: 43, type: !6) +; CHECK-NEXT: !53 = distinct !DILexicalBlock(scope: !44, file: !1, line: 42) +; CHECK-NEXT: !54 = !DILocalVariable(name: "e", scope: !53, file: !1, line: 44, type: !6) +; CHECK-NEXT: !55 = !DILabel(scope: !44, name: "label3", file: !1, line: 42) +; CHECK-NEXT: !56 = !DILocation(line: 42, scope: !44) +; CHECK-NEXT: !57 = !DILabel(scope: !44, name: "label1", file: !1, line: 42) +; CHECK-NEXT: !58 = !DILabel(scope: !44, name: "label2", file: !1, line: 42) +; CHECK-NEXT: !59 = !DILocation(line: 43, scope: !44) From f420b613c92669070e1385d8abc48afbc841717d Mon Sep 17 00:00:00 2001 From: peter mckinna Date: Tue, 13 May 2025 09:22:43 +1000 Subject: [PATCH 4/7] Fixed unwrap for subrange type failing asserts. Also fixed the replace arrays test. --- llvm/lib/IR/DebugInfo.cpp | 11 ++- .../Bindings/llvm-c/debug_info_new_format.ll | 77 ++++++++++--------- llvm/tools/llvm-c-test/debuginfo.c | 28 ++++--- 3 files changed, 64 insertions(+), 52 deletions(-) diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 9b1277f4f397b..65f8862cd7e58 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1339,9 +1339,8 @@ LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( return wrap(unwrap(Builder)->createSubrangeType( {Name, NameLen}, unwrapDI(File), LineNo, unwrapDI(Scope), SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags), - unwrapDI(BaseTy), unwrap(LowerBound), - unwrap(UpperBound), unwrap(Stride), - unwrap(Bias))); + unwrapDI(BaseTy), unwrap(LowerBound), unwrap(UpperBound), + unwrap(Stride), unwrap(Bias))); } LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( @@ -1356,17 +1355,17 @@ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( return wrap(unwrap(Builder)->createArrayType( unwrapDI(Scope), {Name, NameLen}, unwrapDI(File), LineNo, Size, AlignInBits, unwrapDI(Ty), Subs, - unwrap(DataLocation), unwrap(Associated), + unwrapDI(DataLocation), unwrap(Associated), unwrap(Allocated), unwrap(Rank), unwrap(BitStride))); } void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T, LLVMMetadataRef *Elements, unsigned NumElements) { - auto Arr = unwrap(*T); + auto CT = unwrap(*T); auto Elts = unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements}); - unwrap(Builder)->replaceArrays(Arr, Elts); + unwrap(Builder)->replaceArrays(CT, Elts); } LLVMMetadataRef LLVMDIBuilderCreateUnionType( diff --git a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll index 91ffd05cc0bbc..4f0fd29caf05b 100644 --- a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll +++ b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll @@ -4,21 +4,21 @@ ; CHECK: ; ModuleID = 'debuginfo.c' ; CHECK-NEXT: source_filename = "debuginfo.c" -; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !44 { +; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !46 { ; CHECK-NEXT: entry: -; CHECK-NEXT: #dbg_declare(i64 0, !49, !DIExpression(), !56) -; CHECK-NEXT: #dbg_declare(i64 0, !50, !DIExpression(), !56) -; CHECK-NEXT: #dbg_declare(i64 0, !51, !DIExpression(), !56) -; CHECK-NEXT: #dbg_label(!57, !56) +; CHECK-NEXT: #dbg_declare(i64 0, !51, !DIExpression(), !58) +; CHECK-NEXT: #dbg_declare(i64 0, !52, !DIExpression(), !58) +; CHECK-NEXT: #dbg_declare(i64 0, !53, !DIExpression(), !58) +; CHECK-NEXT: #dbg_label(!59, !58) ; CHECK-NEXT: br label %vars -; CHECK-NEXT: #dbg_label(!58, !56) +; CHECK-NEXT: #dbg_label(!60, !58) ; CHECK-NEXT: br label %vars ; CHECK: vars: ; preds = %entry, %entry ; CHECK-NEXT: %p1 = phi i64 [ 0, %entry ] ; CHECK-NEXT: %p2 = phi i64 [ 0, %entry ] -; CHECK-NEXT: #dbg_value(i64 0, !52, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !59) -; CHECK-NEXT: #dbg_value(i64 1, !54, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !59) +; CHECK-NEXT: #dbg_value(i64 0, !54, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !61) +; CHECK-NEXT: #dbg_value(i64 1, !56, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !61) ; CHECK-NEXT: %a = add i64 %p1, %p2 ; CHECK-NEXT: ret i64 0 ; CHECK-NEXT: } @@ -27,10 +27,11 @@ ; CHECK-NEXT: !FooType = !{!33} ; CHECK-NEXT: !EnumTest = !{!3} ; CHECK-NEXT: !LargeEnumTest = !{!11} -; CHECK-NEXT: !SubrangeType = !{!38} -; CHECK-NEXT: !SetType1 = !{!39} -; CHECK-NEXT: !SetType2 = !{!40} -; CHECK-NEXT: !DynType = !{!41} +; CHECK-NEXT: !SubrangeType = !{!36} +; CHECK-NEXT: !SetType1 = !{!37} +; CHECK-NEXT: !SetType2 = !{!38} +; CHECK-NEXT: !DynType = !{!39} +; CHECK-NEXT: !ClassType = !{!42} ; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !16, imports: !24, macros: !28, splitDebugInlining: false, sysroot: "/") ; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c", directory: ".") @@ -67,28 +68,30 @@ ; CHECK-NEXT: !32 = !DIMacro(type: DW_MACINFO_define, name: "VALUE_DEFINE", value: "1") ; CHECK-NEXT: !33 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !34, size: 192, dwarfAddressSpace: 0) ; CHECK-NEXT: !34 = !DICompositeType(tag: DW_TAG_structure_type, name: "MyStruct", scope: !4, file: !1, size: 192, elements: !35, runtimeLang: DW_LANG_C89, identifier: "MyStruct") -; CHECK-NEXT: !35 = !{!36} -; CHECK-NEXT: !36 = !DICompositeType(tag: DW_TAG_structure_type, name: "ThisStruc", scope: !4, file: !1, size: 192, elements: !37, runtimeLang: DW_LANG_C89, identifier: "ThisStruc") -; CHECK-NEXT: !37 = !{!6, !6, !6} -; CHECK-NEXT: !38 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1) -; CHECK-NEXT: !39 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64) -; CHECK-NEXT: !40 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !38, size: 64) -; CHECK-NEXT: !41 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !42, dataLocation: !DIExpression()) -; CHECK-NEXT: !42 = !{!43} -; CHECK-NEXT: !43 = !DISubrange(count: 10, lowerBound: 0) -; CHECK-NEXT: !44 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !45, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !48) -; CHECK-NEXT: !45 = !DISubroutineType(types: !46) -; CHECK-NEXT: !46 = !{!6, !6, !47} -; CHECK-NEXT: !47 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !42) -; CHECK-NEXT: !48 = !{!49, !50, !51, !52, !54, !55} -; CHECK-NEXT: !49 = !DILocalVariable(name: "a", arg: 1, scope: !44, file: !1, line: 42, type: !6) -; CHECK-NEXT: !50 = !DILocalVariable(name: "b", arg: 2, scope: !44, file: !1, line: 42, type: !6) -; CHECK-NEXT: !51 = !DILocalVariable(name: "c", arg: 3, scope: !44, file: !1, line: 42, type: !47) -; CHECK-NEXT: !52 = !DILocalVariable(name: "d", scope: !53, file: !1, line: 43, type: !6) -; CHECK-NEXT: !53 = distinct !DILexicalBlock(scope: !44, file: !1, line: 42) -; CHECK-NEXT: !54 = !DILocalVariable(name: "e", scope: !53, file: !1, line: 44, type: !6) -; CHECK-NEXT: !55 = !DILabel(scope: !44, name: "label3", file: !1, line: 42) -; CHECK-NEXT: !56 = !DILocation(line: 42, scope: !44) -; CHECK-NEXT: !57 = !DILabel(scope: !44, name: "label1", file: !1, line: 42) -; CHECK-NEXT: !58 = !DILabel(scope: !44, name: "label2", file: !1, line: 42) -; CHECK-NEXT: !59 = !DILocation(line: 43, scope: !44) +; CHECK-NEXT: !35 = !{!6, !6, !6} +; CHECK-NEXT: !36 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1, stride: i64 8, bias: i64 4) +; CHECK-NEXT: !37 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64) +; CHECK-NEXT: !38 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !36, size: 64) +; CHECK-NEXT: !39 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !40, dataLocation: !DIExpression(), associated: !DIExpression(), allocated: !DIExpression(), rank: !DIExpression()) +; CHECK-NEXT: !40 = !{!41} +; CHECK-NEXT: !41 = !DISubrange(count: 10, lowerBound: 0) +; CHECK-NEXT: !42 = !DICompositeType(tag: DW_TAG_class_type, name: "Class", scope: !4, file: !1, size: 192, flags: DIFlagFwdDecl, elements: !43, identifier: "FooClass") +; CHECK-NEXT: !43 = !{!44} +; CHECK-NEXT: !44 = !{!6, !6, !45} +; CHECK-NEXT: !45 = !DIBasicType(name: "Int32", size: 32) +; CHECK-NEXT: !46 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !47, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !50) +; CHECK-NEXT: !47 = !DISubroutineType(types: !48) +; CHECK-NEXT: !48 = !{!6, !6, !49} +; CHECK-NEXT: !49 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !40) +; CHECK-NEXT: !50 = !{!51, !52, !53, !54, !56, !57} +; CHECK-NEXT: !51 = !DILocalVariable(name: "a", arg: 1, scope: !46, file: !1, line: 42, type: !6) +; CHECK-NEXT: !52 = !DILocalVariable(name: "b", arg: 2, scope: !46, file: !1, line: 42, type: !6) +; CHECK-NEXT: !53 = !DILocalVariable(name: "c", arg: 3, scope: !46, file: !1, line: 42, type: !49) +; CHECK-NEXT: !54 = !DILocalVariable(name: "d", scope: !55, file: !1, line: 43, type: !6) +; CHECK-NEXT: !55 = distinct !DILexicalBlock(scope: !46, file: !1, line: 42) +; CHECK-NEXT: !56 = !DILocalVariable(name: "e", scope: !55, file: !1, line: 44, type: !6) +; CHECK-NEXT: !57 = !DILabel(scope: !46, name: "label3", file: !1, line: 42) +; CHECK-NEXT: !58 = !DILocation(line: 42, scope: !46) +; CHECK-NEXT: !59 = !DILabel(scope: !46, name: "label1", file: !1, line: 42) +; CHECK-NEXT: !60 = !DILabel(scope: !46, name: "label2", file: !1, line: 42) +; CHECK-NEXT: !61 = !DILocation(line: 43, scope: !46) diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c index 694c206d467c9..c8d72d4fef3e4 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -235,10 +235,14 @@ int llvm_test_dibuilder(void) { M, "LargeEnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), LargeEnumTest)); + LLVMValueRef FooVal3 = LLVMConstInt(LLVMInt64Type(), 8, false); + LLVMValueRef FooVal4 = LLVMConstInt(LLVMInt64Type(), 4, false); LLVMMetadataRef lo = LLVMValueAsMetadata(FooVal1); LLVMMetadataRef hi = LLVMValueAsMetadata(FooVal2); + LLVMMetadataRef strd = LLVMValueAsMetadata(FooVal3); + LLVMMetadataRef bias = LLVMValueAsMetadata(FooVal4); LLVMMetadataRef SubrangeMetadataTy = LLVMDIBuilderCreateSubrangeType( - DIB, File, "foo", 3, 42, File, 64, 0, 0, Int64Ty, lo, hi, NULL, NULL); + DIB, File, "foo", 3, 42, File, 64, 0, 0, Int64Ty, lo, hi, strd, bias); LLVMAddNamedMetadataOperand( M, "SubrangeType", LLVMMetadataAsValue(LLVMGetModuleContext(M), SubrangeMetadataTy)); @@ -257,19 +261,25 @@ int llvm_test_dibuilder(void) { LLVMMetadataRef DynSubscripts[] = { LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10), }; - LLVMMetadataRef LocExpression = LLVMDIBuilderCreateExpression(DIB, NULL, 0); + LLVMMetadataRef L = LLVMDIBuilderCreateExpression(DIB, NULL, 0); LLVMMetadataRef DynamicArrayMetadataTy = LLVMDIBuilderCreateDynamicArrayType( - DIB, File, "foo", 3, 42, File, 64 * 10, 0, Int64Ty, DynSubscripts, 1, - LocExpression, NULL, NULL, NULL, NULL); + DIB, File, "foo", 3, 42, File, 64 * 10, 0, Int64Ty, DynSubscripts, 1, L, + L, L, L, NULL); LLVMAddNamedMetadataOperand( M, "DynType", LLVMMetadataAsValue(LLVMGetModuleContext(M), DynamicArrayMetadataTy)); - LLVMMetadataRef StructElts[] = {Int64Ty, Int64Ty, Int64Ty}; - LLVMMetadataRef StructDestTy = LLVMDIBuilderCreateStructType( - DIB, NameSpace, "ThisStruct", 9, File, 0, 192, 0, 0, NULL, StructElts, 3, - LLVMDWARFSourceLanguageC, NULL, "ThisStruct", 9); - LLVMReplaceArrays(DIB, &StructDbgTy, &StructDestTy, 1); + LLVMMetadataRef StructPTy = LLVMDIBuilderCreateForwardDecl( + DIB, 2 /*DW_TAG_class_type*/, "Class1", 5, NameSpace, File, 0, 0, 192, 0, + "FooClass", 8); + + LLVMMetadataRef Int32Ty = + LLVMDIBuilderCreateBasicType(DIB, "Int32", 5, 32, 0, LLVMDIFlagZero); + LLVMMetadataRef StructElts[] = {Int64Ty, Int64Ty, Int32Ty}; + LLVMMetadataRef ClassArr = LLVMDIBuilderGetOrCreateArray(DIB, StructElts, 3); + LLVMReplaceArrays(DIB, &StructPTy, &ClassArr, 1); + LLVMAddNamedMetadataOperand( + M, "ClassType", LLVMMetadataAsValue(LLVMGetModuleContext(M), StructPTy)); // Using the new debug format, debug records get attached to instructions. // Insert a `br` and `ret` now to absorb the debug records which are From c2324e1d9824d3ad1ec54d83460688770d1cf669 Mon Sep 17 00:00:00 2001 From: peter mckinna Date: Tue, 27 May 2025 09:35:21 +1000 Subject: [PATCH 5/7] Added extra restrictions to some debug function parameters that cannot be NULL. --- llvm/include/llvm-c/DebugInfo.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 3c68282875dd7..448845bde2f08 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -751,9 +751,9 @@ LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( * \param Subscripts Subscripts. * \param NumSubscripts Number of subscripts. * \param DataLocation DataLocation. - * \param Associated Associated. - * \param Allocated Allocated. - * \param Rank Rank. + * \param Associated Associated (not NULL). + * \param Allocated Allocated (not NULL). + * \param Rank Rank (not NULL). * \param BitStride BitStride. */ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( From d303eee42cda0de799573c6f82d1b022f294c247 Mon Sep 17 00:00:00 2001 From: peter mckinna Date: Tue, 3 Jun 2025 21:20:20 +1000 Subject: [PATCH 6/7] Change unwind to unwindDI to allow nulls --- llvm/include/llvm-c/DebugInfo.h | 6 +++--- llvm/lib/IR/DebugInfo.cpp | 4 ++-- llvm/test/Bindings/llvm-c/debug_info_new_format.ll | 2 +- llvm/tools/llvm-c-test/debuginfo.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 448845bde2f08..3c68282875dd7 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -751,9 +751,9 @@ LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( * \param Subscripts Subscripts. * \param NumSubscripts Number of subscripts. * \param DataLocation DataLocation. - * \param Associated Associated (not NULL). - * \param Allocated Allocated (not NULL). - * \param Rank Rank (not NULL). + * \param Associated Associated. + * \param Allocated Allocated. + * \param Rank Rank. * \param BitStride BitStride. */ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 65f8862cd7e58..529f4ccd0fb75 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1355,8 +1355,8 @@ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( return wrap(unwrap(Builder)->createArrayType( unwrapDI(Scope), {Name, NameLen}, unwrapDI(File), LineNo, Size, AlignInBits, unwrapDI(Ty), Subs, - unwrapDI(DataLocation), unwrap(Associated), - unwrap(Allocated), unwrap(Rank), + unwrapDI(DataLocation), unwrapDI(Associated), + unwrapDI(Allocated), unwrapDI(Rank), unwrap(BitStride))); } diff --git a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll index 4f0fd29caf05b..1e91044495db1 100644 --- a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll +++ b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll @@ -72,7 +72,7 @@ ; CHECK-NEXT: !36 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1, stride: i64 8, bias: i64 4) ; CHECK-NEXT: !37 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64) ; CHECK-NEXT: !38 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !36, size: 64) -; CHECK-NEXT: !39 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !40, dataLocation: !DIExpression(), associated: !DIExpression(), allocated: !DIExpression(), rank: !DIExpression()) +; CHECK-NEXT: !39 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !40, dataLocation: !DIExpression()) ; CHECK-NEXT: !40 = !{!41} ; CHECK-NEXT: !41 = !DISubrange(count: 10, lowerBound: 0) ; CHECK-NEXT: !42 = !DICompositeType(tag: DW_TAG_class_type, name: "Class", scope: !4, file: !1, size: 192, flags: DIFlagFwdDecl, elements: !43, identifier: "FooClass") diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c index c8d72d4fef3e4..90c4191c1acf1 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -264,7 +264,7 @@ int llvm_test_dibuilder(void) { LLVMMetadataRef L = LLVMDIBuilderCreateExpression(DIB, NULL, 0); LLVMMetadataRef DynamicArrayMetadataTy = LLVMDIBuilderCreateDynamicArrayType( DIB, File, "foo", 3, 42, File, 64 * 10, 0, Int64Ty, DynSubscripts, 1, L, - L, L, L, NULL); + NULL, NULL, NULL, NULL); LLVMAddNamedMetadataOperand( M, "DynType", LLVMMetadataAsValue(LLVMGetModuleContext(M), DynamicArrayMetadataTy)); From ace58d6383eea9ecee7aeb06fd0ffa5c2f66a50e Mon Sep 17 00:00:00 2001 From: peter mckinna Date: Wed, 25 Jun 2025 15:48:18 +1000 Subject: [PATCH 7/7] Update to better reflect the different parameter types that can be given to CreateDynamicArray. Plus additional tests to check. --- llvm/include/llvm-c/DebugInfo.h | 8 +-- llvm/lib/IR/DebugInfo.cpp | 16 ++++-- .../Bindings/llvm-c/debug_info_new_format.ll | 54 +++++++++---------- llvm/tools/llvm-c-test/debuginfo.c | 7 +-- 4 files changed, 48 insertions(+), 37 deletions(-) diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h index 3c68282875dd7..47abd049a11d4 100644 --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -750,10 +750,10 @@ LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( * \param Ty Element type. * \param Subscripts Subscripts. * \param NumSubscripts Number of subscripts. - * \param DataLocation DataLocation. - * \param Associated Associated. - * \param Allocated Allocated. - * \param Rank Rank. + * \param DataLocation DataLocation. (DIVariable, DIExpression or NULL) + * \param Associated Associated. (DIVariable, DIExpression or NULL) + * \param Allocated Allocated. (DIVariable, DIExpression or NULL) + * \param Rank Rank. (DIVariable, DIExpression or NULL) * \param BitStride BitStride. */ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp index 529f4ccd0fb75..3f82d421e98fe 100644 --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1343,6 +1343,17 @@ LLVMMetadataRef LLVMDIBuilderCreateSubrangeType( unwrap(Stride), unwrap(Bias))); } +/// MD may be nullptr, a DIExpression or DIVariable. +PointerUnion unwrapExprVar(LLVMMetadataRef MD) { + if (!MD) + return nullptr; + MDNode *MDN = unwrapDI(MD); + if (auto *E = dyn_cast(MDN)) + return E; + assert(isa(MDN) && "Expected DIExpression or DIVariable"); + return cast(MDN); +} + LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name, size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t Size, @@ -1355,9 +1366,8 @@ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType( return wrap(unwrap(Builder)->createArrayType( unwrapDI(Scope), {Name, NameLen}, unwrapDI(File), LineNo, Size, AlignInBits, unwrapDI(Ty), Subs, - unwrapDI(DataLocation), unwrapDI(Associated), - unwrapDI(Allocated), unwrapDI(Rank), - unwrap(BitStride))); + unwrapExprVar(DataLocation), unwrapExprVar(Associated), + unwrapExprVar(Allocated), unwrapExprVar(Rank), unwrap(BitStride))); } void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T, diff --git a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll index 1e91044495db1..83b37da759b5c 100644 --- a/llvm/test/Bindings/llvm-c/debug_info_new_format.ll +++ b/llvm/test/Bindings/llvm-c/debug_info_new_format.ll @@ -4,11 +4,11 @@ ; CHECK: ; ModuleID = 'debuginfo.c' ; CHECK-NEXT: source_filename = "debuginfo.c" -; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !46 { +; CHECK: define i64 @foo(i64 %0, i64 %1, <10 x i64> %2) !dbg !44 { ; CHECK-NEXT: entry: +; CHECK-NEXT: #dbg_declare(i64 0, !49, !DIExpression(), !58) +; CHECK-NEXT: #dbg_declare(i64 0, !50, !DIExpression(), !58) ; CHECK-NEXT: #dbg_declare(i64 0, !51, !DIExpression(), !58) -; CHECK-NEXT: #dbg_declare(i64 0, !52, !DIExpression(), !58) -; CHECK-NEXT: #dbg_declare(i64 0, !53, !DIExpression(), !58) ; CHECK-NEXT: #dbg_label(!59, !58) ; CHECK-NEXT: br label %vars ; CHECK-NEXT: #dbg_label(!60, !58) @@ -17,8 +17,8 @@ ; CHECK: vars: ; preds = %entry, %entry ; CHECK-NEXT: %p1 = phi i64 [ 0, %entry ] ; CHECK-NEXT: %p2 = phi i64 [ 0, %entry ] -; CHECK-NEXT: #dbg_value(i64 0, !54, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !61) -; CHECK-NEXT: #dbg_value(i64 1, !56, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !61) +; CHECK-NEXT: #dbg_value(i64 0, !42, !DIExpression(DW_OP_constu, 0, DW_OP_stack_value), !61) +; CHECK-NEXT: #dbg_value(i64 1, !52, !DIExpression(DW_OP_constu, 1, DW_OP_stack_value), !61) ; CHECK-NEXT: %a = add i64 %p1, %p2 ; CHECK-NEXT: ret i64 0 ; CHECK-NEXT: } @@ -31,7 +31,7 @@ ; CHECK-NEXT: !SetType1 = !{!37} ; CHECK-NEXT: !SetType2 = !{!38} ; CHECK-NEXT: !DynType = !{!39} -; CHECK-NEXT: !ClassType = !{!42} +; CHECK-NEXT: !ClassType = !{!54} ; CHECK: !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "llvm-c-test", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, globals: !16, imports: !24, macros: !28, splitDebugInlining: false, sysroot: "/") ; CHECK-NEXT: !1 = !DIFile(filename: "debuginfo.c", directory: ".") @@ -72,26 +72,26 @@ ; CHECK-NEXT: !36 = !DISubrangeType(name: "foo", scope: !1, file: !1, line: 42, size: 64, baseType: !6, lowerBound: i64 0, upperBound: i64 1, stride: i64 8, bias: i64 4) ; CHECK-NEXT: !37 = !DIDerivedType(tag: DW_TAG_set_type, name: "enumset", scope: !1, file: !1, line: 42, baseType: !3, size: 64) ; CHECK-NEXT: !38 = !DIDerivedType(tag: DW_TAG_set_type, name: "subrangeset", scope: !1, file: !1, line: 42, baseType: !36, size: 64) -; CHECK-NEXT: !39 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !40, dataLocation: !DIExpression()) +; CHECK-NEXT: !39 = !DICompositeType(tag: DW_TAG_array_type, name: "foo", scope: !1, file: !1, line: 42, baseType: !6, size: 640, elements: !40, dataLocation: !DIExpression(), associated: !42, rank: !DIExpression()) ; CHECK-NEXT: !40 = !{!41} ; CHECK-NEXT: !41 = !DISubrange(count: 10, lowerBound: 0) -; CHECK-NEXT: !42 = !DICompositeType(tag: DW_TAG_class_type, name: "Class", scope: !4, file: !1, size: 192, flags: DIFlagFwdDecl, elements: !43, identifier: "FooClass") -; CHECK-NEXT: !43 = !{!44} -; CHECK-NEXT: !44 = !{!6, !6, !45} -; CHECK-NEXT: !45 = !DIBasicType(name: "Int32", size: 32) -; CHECK-NEXT: !46 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !47, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !50) -; CHECK-NEXT: !47 = !DISubroutineType(types: !48) -; CHECK-NEXT: !48 = !{!6, !6, !49} -; CHECK-NEXT: !49 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !40) -; CHECK-NEXT: !50 = !{!51, !52, !53, !54, !56, !57} -; CHECK-NEXT: !51 = !DILocalVariable(name: "a", arg: 1, scope: !46, file: !1, line: 42, type: !6) -; CHECK-NEXT: !52 = !DILocalVariable(name: "b", arg: 2, scope: !46, file: !1, line: 42, type: !6) -; CHECK-NEXT: !53 = !DILocalVariable(name: "c", arg: 3, scope: !46, file: !1, line: 42, type: !49) -; CHECK-NEXT: !54 = !DILocalVariable(name: "d", scope: !55, file: !1, line: 43, type: !6) -; CHECK-NEXT: !55 = distinct !DILexicalBlock(scope: !46, file: !1, line: 42) -; CHECK-NEXT: !56 = !DILocalVariable(name: "e", scope: !55, file: !1, line: 44, type: !6) -; CHECK-NEXT: !57 = !DILabel(scope: !46, name: "label3", file: !1, line: 42) -; CHECK-NEXT: !58 = !DILocation(line: 42, scope: !46) -; CHECK-NEXT: !59 = !DILabel(scope: !46, name: "label1", file: !1, line: 42) -; CHECK-NEXT: !60 = !DILabel(scope: !46, name: "label2", file: !1, line: 42) -; CHECK-NEXT: !61 = !DILocation(line: 43, scope: !46) +; CHECK-NEXT: !42 = !DILocalVariable(name: "d", scope: !43, file: !1, line: 43, type: !6) +; CHECK-NEXT: !43 = distinct !DILexicalBlock(scope: !44, file: !1, line: 42) +; CHECK-NEXT: !44 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: !1, file: !1, line: 42, type: !45, scopeLine: 42, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !0, retainedNodes: !48) +; CHECK-NEXT: !45 = !DISubroutineType(types: !46) +; CHECK-NEXT: !46 = !{!6, !6, !47} +; CHECK-NEXT: !47 = !DICompositeType(tag: DW_TAG_array_type, baseType: !6, size: 640, flags: DIFlagVector, elements: !40) +; CHECK-NEXT: !48 = !{!49, !50, !51, !42, !52, !53} +; CHECK-NEXT: !49 = !DILocalVariable(name: "a", arg: 1, scope: !44, file: !1, line: 42, type: !6) +; CHECK-NEXT: !50 = !DILocalVariable(name: "b", arg: 2, scope: !44, file: !1, line: 42, type: !6) +; CHECK-NEXT: !51 = !DILocalVariable(name: "c", arg: 3, scope: !44, file: !1, line: 42, type: !47) +; CHECK-NEXT: !52 = !DILocalVariable(name: "e", scope: !43, file: !1, line: 44, type: !6) +; CHECK-NEXT: !53 = !DILabel(scope: !44, name: "label3", file: !1, line: 42) +; CHECK-NEXT: !54 = !DICompositeType(tag: DW_TAG_class_type, name: "Class", scope: !4, file: !1, size: 192, flags: DIFlagFwdDecl, elements: !55, identifier: "FooClass") +; CHECK-NEXT: !55 = !{!56} +; CHECK-NEXT: !56 = !{!6, !6, !57} +; CHECK-NEXT: !57 = !DIBasicType(name: "Int32", size: 32) +; CHECK-NEXT: !58 = !DILocation(line: 42, scope: !44) +; CHECK-NEXT: !59 = !DILabel(scope: !44, name: "label1", file: !1, line: 42) +; CHECK-NEXT: !60 = !DILabel(scope: !44, name: "label2", file: !1, line: 42) +; CHECK-NEXT: !61 = !DILocation(line: 43, scope: !44) diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c index 90c4191c1acf1..f0f01a0f4233c 100644 --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -261,10 +261,11 @@ int llvm_test_dibuilder(void) { LLVMMetadataRef DynSubscripts[] = { LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10), }; - LLVMMetadataRef L = LLVMDIBuilderCreateExpression(DIB, NULL, 0); + LLVMMetadataRef Loc = LLVMDIBuilderCreateExpression(DIB, NULL, 0); + LLVMMetadataRef Rank = LLVMDIBuilderCreateExpression(DIB, NULL, 0); LLVMMetadataRef DynamicArrayMetadataTy = LLVMDIBuilderCreateDynamicArrayType( - DIB, File, "foo", 3, 42, File, 64 * 10, 0, Int64Ty, DynSubscripts, 1, L, - NULL, NULL, NULL, NULL); + DIB, File, "foo", 3, 42, File, 64 * 10, 0, Int64Ty, DynSubscripts, 1, Loc, + FooVar1, NULL, Rank, NULL); LLVMAddNamedMetadataOperand( M, "DynType", LLVMMetadataAsValue(LLVMGetModuleContext(M), DynamicArrayMetadataTy));