[llvm] Add debuginfo C support for a SetType, Subrangetype, dynamic array type and replace arrays (PR #135607)

peter mckinna via llvm-commits llvm-commits at lists.llvm.org
Mon May 26 16:39:50 PDT 2025


https://github.com/demoitem updated https://github.com/llvm/llvm-project/pull/135607

>From bac7e2106fc7ed9f09694b167d2dab8a541cb3c6 Mon Sep 17 00:00:00 2001
From: peter mckinna <peter.mckinna at gmail.com>
Date: Mon, 14 Apr 2025 19:31:32 +1000
Subject: [PATCH 1/5] 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<DIType>(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<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File),
+      LineNumber, SizeInBits, AlignInBits, unwrapDI<DIType>(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<DIFile>(File), LineNo,
+	  unwrapDI<DIScope>(Scope), SizeInBits, AlignInBits,
+	  map_from_llvmDIFlags(Flags), unwrapDI<DIType>(BaseTy),
+          unwrap<DIExpression>(LowerBound), unwrap<DIExpression>(UpperBound),
+          unwrap<DIExpression>(Stride), unwrap<DIExpression>(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<DIScope>(Scope),
+      {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,
+      Size, AlignInBits, unwrapDI<DIType>(Ty), Subs,
+      unwrap<DIExpression>(DataLocation), unwrap<DIExpression>(Associated),
+      unwrap<DIExpression>(Allocated), unwrap<DIExpression>(Rank),
+      unwrap(BitStride)));
+}
+
+void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T,
+                       LLVMMetadataRef *Elements, unsigned NumElements) {
+  auto Arr = unwrap<DICompositeType>(*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 <peter.mckinna at gmail.com>
Date: Mon, 14 Apr 2025 19:31:32 +1000
Subject: [PATCH 2/5] 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<DIFile>(File), LineNo,
-	  unwrapDI<DIScope>(Scope), SizeInBits, AlignInBits,
-	  map_from_llvmDIFlags(Flags), unwrapDI<DIType>(BaseTy),
-          unwrap<DIExpression>(LowerBound), unwrap<DIExpression>(UpperBound),
-          unwrap<DIExpression>(Stride), unwrap<DIExpression>(Bias)));
+      {Name, NameLen}, unwrapDI<DIFile>(File), LineNo, unwrapDI<DIScope>(Scope),
+      SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags),
+      unwrapDI<DIType>(BaseTy), unwrap<DIExpression>(LowerBound),
+      unwrap<DIExpression>(UpperBound), unwrap<DIExpression>(Stride),
+      unwrap<DIExpression>(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<DIScope>(Scope),
-      {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,
+      unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,
       Size, AlignInBits, unwrapDI<DIType>(Ty), Subs,
       unwrap<DIExpression>(DataLocation), unwrap<DIExpression>(Associated),
       unwrap<DIExpression>(Allocated), unwrap<DIExpression>(Rank),
@@ -1367,8 +1364,8 @@ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType(
 void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T,
                        LLVMMetadataRef *Elements, unsigned NumElements) {
   auto Arr = unwrap<DICompositeType>(*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 <peter.mckinna at gmail.com>
Date: Wed, 7 May 2025 09:43:28 +1000
Subject: [PATCH 3/5] 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 <peter.mckinna at gmail.com>
Date: Tue, 13 May 2025 09:22:43 +1000
Subject: [PATCH 4/5] 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<DIFile>(File), LineNo, unwrapDI<DIScope>(Scope),
       SizeInBits, AlignInBits, map_from_llvmDIFlags(Flags),
-      unwrapDI<DIType>(BaseTy), unwrap<DIExpression>(LowerBound),
-      unwrap<DIExpression>(UpperBound), unwrap<DIExpression>(Stride),
-      unwrap<DIExpression>(Bias)));
+      unwrapDI<DIType>(BaseTy), unwrap(LowerBound), unwrap(UpperBound),
+      unwrap(Stride), unwrap(Bias)));
 }
 
 LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType(
@@ -1356,17 +1355,17 @@ LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType(
   return wrap(unwrap(Builder)->createArrayType(
       unwrapDI<DIScope>(Scope), {Name, NameLen}, unwrapDI<DIFile>(File), LineNo,
       Size, AlignInBits, unwrapDI<DIType>(Ty), Subs,
-      unwrap<DIExpression>(DataLocation), unwrap<DIExpression>(Associated),
+      unwrapDI<DIExpression>(DataLocation), unwrap<DIExpression>(Associated),
       unwrap<DIExpression>(Allocated), unwrap<DIExpression>(Rank),
       unwrap(BitStride)));
 }
 
 void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T,
                        LLVMMetadataRef *Elements, unsigned NumElements) {
-  auto Arr = unwrap<DICompositeType>(*T);
+  auto CT = unwrap<DICompositeType>(*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 <peter.mckinna at gmail.com>
Date: Tue, 27 May 2025 09:35:21 +1000
Subject: [PATCH 5/5] 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(



More information about the llvm-commits mailing list