Skip to content

Commit

Permalink
Use the 'count' attribute instead of the 'upper_bound' attribute.
Browse files Browse the repository at this point in the history
If we have a type 'int a[1]' and a type 'int b[0]', the generated DWARF is the
same for both of them because we use the 'upper_bound' attribute. Instead use
the 'count' attrbute, which gives the correct number of elements in the array.
<rdar://problem/12566646>


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@167807 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
isanbard committed Nov 13, 2012
1 parent 8187c7e commit 30305be
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 10 deletions.
21 changes: 12 additions & 9 deletions lib/CodeGen/CGDebugInfo.cpp
Expand Up @@ -1473,23 +1473,23 @@ llvm::DIType CGDebugInfo::CreateType(const ObjCInterfaceType *Ty,

llvm::DIType CGDebugInfo::CreateType(const VectorType *Ty, llvm::DIFile Unit) {
llvm::DIType ElementTy = getOrCreateType(Ty->getElementType(), Unit);
int64_t NumElems = Ty->getNumElements();
int64_t UpperBound = Ty->getNumElements();
int64_t LowerBound = 0;
if (NumElems == 0)
if (UpperBound == 0)
// If number of elements are not known then this is an unbounded array.
// Use Low = 1, Hi = 0 to express such arrays.
LowerBound = 1;
else
--NumElems;
--UpperBound;

llvm::Value *Subscript = DBuilder.getOrCreateSubrange(LowerBound, NumElems);
llvm::Value *Subscript = DBuilder.getOrCreateSubrange(LowerBound, UpperBound,
Ty->getNumElements());
llvm::DIArray SubscriptArray = DBuilder.getOrCreateArray(Subscript);

uint64_t Size = CGM.getContext().getTypeSize(Ty);
uint64_t Align = CGM.getContext().getTypeAlign(Ty);

return
DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
return DBuilder.createVectorType(Size, Align, ElementTy, SubscriptArray);
}

llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
Expand Down Expand Up @@ -1525,17 +1525,20 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty,
while ((Ty = dyn_cast<ArrayType>(EltTy))) {
int64_t UpperBound = 0;
int64_t LowerBound = 0;
uint64_t Count = 0;
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty)) {
if (CAT->getSize().getZExtValue())
UpperBound = CAT->getSize().getZExtValue() - 1;
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();
}

Expand Down
33 changes: 33 additions & 0 deletions test/CodeGen/debug-info-zero-length-arrays.c
@@ -0,0 +1,33 @@
// RUN: %clang -emit-llvm -S -g %s -o - | FileCheck %s

// <rdar://problem/12566646>

// The subrange for a type 'int[1]' and 'int[0]' should be different. Use the
// 'count' attribute instead of the 'upper_bound' attribute do disabmiguate the
// DIE.

struct foo {
int a;
int b[1];
};

struct bar {
int a;
int b[0];
};

int main()
{
struct foo my_foo;
struct bar my_bar;

my_foo.a = 3;
my_bar.a = 5;

return my_foo.a + my_bar.a;
}

// The third metadata operand is the count.
//
// CHECK: metadata !{i32 786465, i64 0, i64 0, i64 1} ; [ DW_TAG_subrange_type ]
// CHECK: metadata !{i32 786465, i64 0, i64 0, i64 0} ; [ DW_TAG_subrange_type ]
2 changes: 1 addition & 1 deletion 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 0} ; [ DW_TAG_subrange_type ]

struct StructName {
int member[];
Expand Down

0 comments on commit 30305be

Please sign in to comment.