aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/debug
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/debug')
-rw-r--r--src/pkg/debug/dwarf/type.go52
1 files changed, 29 insertions, 23 deletions
diff --git a/src/pkg/debug/dwarf/type.go b/src/pkg/debug/dwarf/type.go
index b64333ecc5..fa40b2bef1 100644
--- a/src/pkg/debug/dwarf/type.go
+++ b/src/pkg/debug/dwarf/type.go
@@ -118,7 +118,12 @@ func (t *ArrayType) String() string {
return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
}
-func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
+func (t *ArrayType) Size() int64 {
+ if t.Count == -1 {
+ return 0
+ }
+ return t.Count * t.Type.Size()
+}
// A VoidType represents the C void type.
type VoidType struct {
@@ -369,7 +374,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
// Accumulate dimensions,
- ndim := 0
+ var dims []int64
for kid := next(); kid != nil; kid = next() {
// TODO(rsc): Can also be TagEnumerationType
// but haven't seen that in the wild yet.
@@ -381,26 +386,24 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
count, ok = kid.Val(AttrUpperBound).(int64)
if ok {
count++ // Length is one more than upper bound.
- } else {
+ } else if len(dims) == 0 {
count = -1 // As in x[].
}
}
- if ndim == 0 {
- t.Count = count
- } else {
- // Multidimensional array.
- // Create new array type underneath this one.
- t.Type = &ArrayType{Type: t.Type, Count: count}
- }
- ndim++
+ dims = append(dims, count)
case TagEnumerationType:
err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
goto Error
}
}
- if ndim == 0 {
+ if len(dims) == 0 {
// LLVM generates this for x[].
- t.Count = -1
+ dims = []int64{-1}
+ }
+
+ t.Count = dims[0]
+ for i := len(dims) - 1; i >= 1; i-- {
+ t.Type = &ArrayType{Type: t.Type, Count: dims[i]}
}
case TagBaseType:
@@ -476,7 +479,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
t.StructName, _ = e.Val(AttrName).(string)
t.Incomplete = e.Val(AttrDeclaration) != nil
t.Field = make([]*StructField, 0, 8)
- var lastFieldType Type
+ var lastFieldType *Type
var lastFieldBitOffset int64
for kid := next(); kid != nil; kid = next() {
if kid.Tag == TagMember {
@@ -518,7 +521,7 @@ func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Off
// (DWARF writes out 0-length arrays as if they were 1-length arrays.)
zeroArray(lastFieldType)
}
- lastFieldType = f.Type
+ lastFieldType = &f.Type
lastFieldBitOffset = bito
}
}
@@ -667,13 +670,16 @@ Error:
return nil, err
}
-func zeroArray(t Type) {
- for {
- at, ok := t.(*ArrayType)
- if !ok {
- break
- }
- at.Count = 0
- t = at.Type
+func zeroArray(t *Type) {
+ if t == nil {
+ return
+ }
+ at, ok := (*t).(*ArrayType)
+ if !ok || at.Type.Size() == 0 {
+ return
}
+ // Make a copy to avoid invalidating typeCache.
+ tt := *at
+ tt.Count = 0
+ *t = &tt
}