Add a 'count' field to the DWARF subrange.
The count field is necessary because there isn't a difference between the 'lo'
and 'hi' attributes for a one-element array and a zero-element array. When the
count is '0', we know that this is a zero-element array. When it's >=1, then
it's a normal constant sized array. When it's -1, then the array is unbounded.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169219 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 96cfd28..666b6a8 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1475,6 +1475,7 @@
llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit);
int64_t NumElems = Ty->getNumElements();
int64_t LowerBound = 0;
+ int64_t Count = NumElems;
if (NumElems == 0)
// If number of elements are not known then this is an unbounded array.
// Use Low = 1, Hi = 0 to express such arrays.
@@ -1482,7 +1483,8 @@
else
--NumElems;
- llvm::Value *Subscript = DBuilder.getOrCreateSubrange(LowerBound, NumElems);
+ llvm::Value *Subscript = DBuilder.getOrCreateSubrange(LowerBound, NumElems,
+ Count);
llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);
uint64_t Size = CGM.getContext().getTypeSize(Ty);
@@ -1523,19 +1525,30 @@
SmallVector<llvm::Value *, 8> Subscripts;
QualType EltTy(Ty, 0);
while ((Ty = dyn_cast<ArrayType>(EltTy))) {
+ // If the number of elements is known, then count is that number. Otherwise,
+ // it's -1. This allows us to represent a subrange with an array of 0
+ // elements, like this:
+ //
+ // struct foo {
+ // int x[0];
+ // };
int64_t UpperBound = 0;
int64_t LowerBound = 0;
+ int64_t Count = -1;
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty)) {
- if (CAT->getSize().getZExtValue())
- UpperBound = CAT->getSize().getZExtValue() - 1;
- } else
+ Count = CAT->getSize().getZExtValue();
+ if (Count)
+ UpperBound = Count - 1;
+ } else {
// This is an unbounded array. Use Low = 1, Hi = 0 to express such
// arrays.
LowerBound = 1;
+ }
// FIXME: Verify this is right for VLAs.
Subscripts.push_back(DBuilder.getOrCreateSubrange(LowerBound,
- UpperBound));
+ UpperBound,
+ Count));
EltTy = Ty->getElementType();
}
diff --git a/test/CodeGenCXX/debug-info-flex-member.cpp b/test/CodeGenCXX/debug-info-flex-member.cpp
index b6aa6da..d38634c 100644
--- a/test/CodeGenCXX/debug-info-flex-member.cpp
+++ b/test/CodeGenCXX/debug-info-flex-member.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
-// CHECK: metadata !{i32 {{.*}}, i64 1, i64 0} ; [ DW_TAG_subrange_type ]
+// CHECK: metadata !{i32 {{.*}}, i64 1, i64 0, i64 -1} ; [ DW_TAG_subrange_type ]
struct StructName {
int member[];
diff --git a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
new file mode 100644
index 0000000..bfbea37
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang -fverbose-asm -g -O0 -S %s -o - | FileCheck %s
+// <rdar://problem/12566646>
+
+class A {
+ int x[];
+};
+A a;
+
+// CHECK: Abbrev [3] 0x2d:0x3 DW_TAG_base_type
+// CHECK-NEXT: DW_AT_byte_size
+// CHECK-NEXT: DW_AT_encoding
+// CHECK-NEXT: Abbrev [4] 0x30:0xb DW_TAG_array_type
+// CHECK-NEXT: DW_AT_type
+// CHECK-NEXT: Abbrev [5] 0x35:0x5 DW_TAG_subrange_type
+// CHECK-NEXT: DW_AT_type
+// CHECK-NEXT: End Of Children Mark