From 1ca9862cfb16641189ba8aff513193af142cd43c Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 4 Dec 2012 06:21:27 +0000 Subject: [PATCH] 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. llvm-svn: 169219 --- clang/lib/CodeGen/CGDebugInfo.cpp | 23 +++++++++++++++++----- clang/test/CodeGenCXX/debug-info-flex-member.cpp | 2 +- .../CodeGenCXX/debug-info-zero-length-arrays.cpp | 16 +++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGenCXX/debug-info-zero-length-arrays.cpp diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 96cfd28..666b6a8 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1475,6 +1475,7 @@ llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile Unit) { 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 @@ llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile Unit) { 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 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, SmallVector Subscripts; QualType EltTy(Ty, 0); while ((Ty = dyn_cast(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(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/clang/test/CodeGenCXX/debug-info-flex-member.cpp b/clang/test/CodeGenCXX/debug-info-flex-member.cpp index b6aa6da..d38634c 100644 --- a/clang/test/CodeGenCXX/debug-info-flex-member.cpp +++ b/clang/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/clang/test/CodeGenCXX/debug-info-zero-length-arrays.cpp b/clang/test/CodeGenCXX/debug-info-zero-length-arrays.cpp new file mode 100644 index 0000000..bfbea37 --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-zero-length-arrays.cpp @@ -0,0 +1,16 @@ +// RUN: %clang -fverbose-asm -g -O0 -S %s -o - | FileCheck %s +// + +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 -- 2.7.4