Skip to content

Commit 993cbea

Browse files
authored
Two fixes for DISubrangeType (#130345)
My previous patch to add DISubrangeType (#126772) had a couple of minor errors. This patch corrects them. 1. When using a DISubrangeType as an array index type, the wrong tag was written into the DIE. 2. I'd intended for subranges to use bit strides, not byte strides -- but neglected to actually implement this. Ada needs bit strides. This patch adds a new test that checks both these things. Finally, this patch adds some documentation for DISubrangeType.
1 parent d90423e commit 993cbea

File tree

3 files changed

+103
-17
lines changed

3 files changed

+103
-17
lines changed

llvm/docs/LangRef.rst

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6319,21 +6319,24 @@ The following ``tag:`` values are valid:
63196319
DW_TAG_union_type = 23
63206320

63216321
For ``DW_TAG_array_type``, the ``elements:`` should be :ref:`subrange
6322-
descriptors <DISubrange>`, each representing the range of subscripts at that
6323-
level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates that an
6324-
array type is a native packed vector. The optional ``dataLocation`` is a
6325-
DIExpression that describes how to get from an object's address to the actual
6326-
raw data, if they aren't equivalent. This is only supported for array types,
6327-
particularly to describe Fortran arrays, which have an array descriptor in
6328-
addition to the array data. Alternatively it can also be DIVariable which
6329-
has the address of the actual raw data. The Fortran language supports pointer
6330-
arrays which can be attached to actual arrays, this attachment between pointer
6331-
and pointee is called association. The optional ``associated`` is a
6332-
DIExpression that describes whether the pointer array is currently associated.
6333-
The optional ``allocated`` is a DIExpression that describes whether the
6334-
allocatable array is currently allocated. The optional ``rank`` is a
6335-
DIExpression that describes the rank (number of dimensions) of fortran assumed
6336-
rank array (rank is known at runtime).
6322+
descriptors <DISubrange>` or :ref:`subrange descriptors
6323+
<DISubrangeType>`, each representing the range of subscripts at that
6324+
level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates
6325+
that an array type is a native packed vector. The optional
6326+
``dataLocation`` is a DIExpression that describes how to get from an
6327+
object's address to the actual raw data, if they aren't
6328+
equivalent. This is only supported for array types, particularly to
6329+
describe Fortran arrays, which have an array descriptor in addition to
6330+
the array data. Alternatively it can also be DIVariable which has the
6331+
address of the actual raw data. The Fortran language supports pointer
6332+
arrays which can be attached to actual arrays, this attachment between
6333+
pointer and pointee is called association. The optional
6334+
``associated`` is a DIExpression that describes whether the pointer
6335+
array is currently associated. The optional ``allocated`` is a
6336+
DIExpression that describes whether the allocatable array is currently
6337+
allocated. The optional ``rank`` is a DIExpression that describes the
6338+
rank (number of dimensions) of fortran assumed rank array (rank is
6339+
known at runtime).
63376340

63386341
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
63396342
descriptors <DIEnumerator>`, each representing the definition of an enumeration
@@ -6378,6 +6381,50 @@ DISubrange
63786381
!12 = !DIGlobalVariable(name: "count", scope: !8, file: !6, line: 22, type: !9)
63796382
!13 = !DISubrange(count: !12, lowerBound: 0)
63806383

6384+
.. _DISubrangeType:
6385+
6386+
DISubrangeType
6387+
""""""""""""""
6388+
6389+
``DISubrangeType`` is similar to ``DISubrange``, but it is also a
6390+
``DIType``. It may be used as the type of an object, but could also
6391+
be used as an array index.
6392+
6393+
Like ``DISubrange``, it can hold a lower bound and count, or a lower
6394+
bound and upper bound. A ``DISubrangeType`` refers to the underlying
6395+
type of which it is a subrange; this type can be an integer type or an
6396+
enumeration type.
6397+
6398+
A ``DISubrangeType`` may also have a stride -- unlike ``DISubrange``,
6399+
this stride is a bit stride. The stride is only useful when a
6400+
``DISubrangeType`` is used as an array index type.
6401+
6402+
Finally, ``DISubrangeType`` may have a bias. In Ada, a program can
6403+
request that a subrange value be stored in the minimum number of bits
6404+
required. In this situation, the stored value is biased by the lower
6405+
bound -- e.g., a range ``-7 .. 0`` may take 3 bits in memory, and the
6406+
value -5 would be stored as 2 (a bias of -7).
6407+
6408+
.. code-block:: text
6409+
6410+
; Scopes used in rest of example
6411+
!0 = !DIFile(filename: "vla.c", directory: "/path/to/file")
6412+
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !0)
6413+
!2 = distinct !DISubprogram(name: "foo", scope: !1, file: !0, line: 5)
6414+
6415+
; Base type used in example.
6416+
!3 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
6417+
6418+
; A simple subrange with a name.
6419+
!4 = !DISubrange(name: "subrange", file: !0, line: 17, size: 32,
6420+
align: 32, baseType: !3, lowerBound: 18, count: 12)
6421+
; A subrange with a bias.
6422+
!5 = !DISubrange(name: "biased", lowerBound: -7, upperBound: 0,
6423+
bias: -7, size: 3)
6424+
; A subrange with a bit stride.
6425+
!6 = !DISubrange(name: "biased", lowerBound: 0, upperBound: 7,
6426+
stride: 3)
6427+
63816428
.. _DIEnumerator:
63826429

63836430
DIEnumerator

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1478,7 +1478,7 @@ void DwarfUnit::constructSubrangeDIE(DIE &DW_Subrange, const DISubrangeType *SR,
14781478

14791479
AddBoundTypeEntry(dwarf::DW_AT_upper_bound, SR->getUpperBound());
14801480

1481-
AddBoundTypeEntry(dwarf::DW_AT_byte_stride, SR->getStride());
1481+
AddBoundTypeEntry(dwarf::DW_AT_bit_stride, SR->getStride());
14821482

14831483
AddBoundTypeEntry(dwarf::DW_AT_GNU_bias, SR->getBias());
14841484
}
@@ -1670,7 +1670,7 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
16701670
DINodeArray Elements = CTy->getElements();
16711671
for (DINode *E : Elements) {
16721672
if (auto *Element = dyn_cast_or_null<DISubrangeType>(E)) {
1673-
DIE &TyDIE = createAndAddDIE(CTy->getTag(), Buffer, CTy);
1673+
DIE &TyDIE = createAndAddDIE(Element->getTag(), Buffer, CTy);
16741674
constructSubrangeDIE(TyDIE, Element, true);
16751675
} else if (auto *Element = dyn_cast_or_null<DISubrange>(E))
16761676
constructSubrangeDIE(Buffer, Element);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
;; Check output of DISubrangeType.
2+
3+
; RUN: %llc_dwarf -filetype=obj -O0 < %s | llvm-dwarfdump -debug-info - | FileCheck %s
4+
5+
; CHECK: DW_TAG_array_type
6+
; CHECK-TYPE: DW_AT_type{{.*}}"unsigned int"
7+
; CHECK-NOT: NULL
8+
; CHECK: DW_TAG_subrange_type
9+
; CHECK-NOT: NULL
10+
; CHECK: DW_AT_lower_bound (-7)
11+
; CHECK-NEXT: DW_AT_upper_bound (0)
12+
; CHECK-NEXT: DW_AT_bit_stride (6)
13+
14+
; ModuleID = 'subrange_type.ll'
15+
source_filename = "/dir/subrange_type.adb"
16+
17+
!llvm.module.flags = !{!0, !1}
18+
!llvm.dbg.cu = !{!2}
19+
20+
!0 = !{i32 2, !"Debug Info Version", i32 3}
21+
!1 = !{i32 2, !"Dwarf Version", i32 4}
22+
!2 = distinct !DICompileUnit(language: DW_LANG_Ada95, file: !3, producer: "GNAT/LLVM", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4)
23+
!3 = !DIFile(filename: "subrange_type.adb", directory: "/dir")
24+
!4 = !{}
25+
!5 = !{!29}
26+
!6 = distinct !DISubprogram(name: "sr", scope: !3, file: !3, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !9)
27+
!7 = !DISubroutineType(types: !8)
28+
!8 = !{null}
29+
!9 = !{!10}
30+
!10 = !DILocalVariable(name: "x", scope: !6, file: !3, line: 3, type: !31, align: 32)
31+
!11 = !DISubrangeType(name: "sr__int_range", file: !3, line: 2, size: 32, align: 32, baseType: !12, lowerBound: i64 -7, upperBound: i64 0, stride: 6)
32+
!12 = !DIBasicType(name: "sr__Tint_rangeB", size: 32, encoding: DW_ATE_signed)
33+
!13 = !DILocation(line: 3, column: 4, scope: !6)
34+
!14 = !DILocation(line: 6, column: 5, scope: !6)
35+
36+
37+
!29 = !DICompositeType(tag: DW_TAG_array_type, size: 64, align: 32, file: !3, scope: !6, baseType: !31, elements: !32)
38+
!31 = !DIBasicType(tag: DW_TAG_base_type, name: "unsigned int", size: 32, align: 32, encoding: DW_ATE_unsigned)
39+
!32 = !{!11}

0 commit comments

Comments
 (0)