SVE intrinsics: Fold svdiv with all-zero operands to zero vector
[official-gcc.git] / libgo / go / debug / dwarf / type.go
blob9c15cfb920612ed49ca570d548c4ef81914baf25
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // DWARF type information structures.
6 // The format is heavily biased toward C, but for simplicity
7 // the String methods use a pseudo-Go syntax.
9 package dwarf
11 import "strconv"
13 // A Type conventionally represents a pointer to any of the
14 // specific Type structures (CharType, StructType, etc.).
15 type Type interface {
16 Common() *CommonType
17 String() string
18 Size() int64
21 // A CommonType holds fields common to multiple types.
22 // If a field is not known or not applicable for a given type,
23 // the zero value is used.
24 type CommonType struct {
25 ByteSize int64 // size of value of this type, in bytes
26 Name string // name that can be used to refer to type
29 func (c *CommonType) Common() *CommonType { return c }
31 func (c *CommonType) Size() int64 { return c.ByteSize }
33 // Basic types
35 // A BasicType holds fields common to all basic types.
37 // See the documentation for StructField for more info on the interpretation of
38 // the BitSize/BitOffset/DataBitOffset fields.
39 type BasicType struct {
40 CommonType
41 BitSize int64
42 BitOffset int64
43 DataBitOffset int64
46 func (b *BasicType) Basic() *BasicType { return b }
48 func (t *BasicType) String() string {
49 if t.Name != "" {
50 return t.Name
52 return "?"
55 // A CharType represents a signed character type.
56 type CharType struct {
57 BasicType
60 // A UcharType represents an unsigned character type.
61 type UcharType struct {
62 BasicType
65 // An IntType represents a signed integer type.
66 type IntType struct {
67 BasicType
70 // A UintType represents an unsigned integer type.
71 type UintType struct {
72 BasicType
75 // A FloatType represents a floating point type.
76 type FloatType struct {
77 BasicType
80 // A ComplexType represents a complex floating point type.
81 type ComplexType struct {
82 BasicType
85 // A BoolType represents a boolean type.
86 type BoolType struct {
87 BasicType
90 // An AddrType represents a machine address type.
91 type AddrType struct {
92 BasicType
95 // An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type.
96 type UnspecifiedType struct {
97 BasicType
100 // qualifiers
102 // A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
103 type QualType struct {
104 CommonType
105 Qual string
106 Type Type
109 func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
111 func (t *QualType) Size() int64 { return t.Type.Size() }
113 // An ArrayType represents a fixed size array type.
114 type ArrayType struct {
115 CommonType
116 Type Type
117 StrideBitSize int64 // if > 0, number of bits to hold each element
118 Count int64 // if == -1, an incomplete array, like char x[].
121 func (t *ArrayType) String() string {
122 return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
125 func (t *ArrayType) Size() int64 {
126 if t.Count == -1 {
127 return 0
129 return t.Count * t.Type.Size()
132 // A VoidType represents the C void type.
133 type VoidType struct {
134 CommonType
137 func (t *VoidType) String() string { return "void" }
139 // A PtrType represents a pointer type.
140 type PtrType struct {
141 CommonType
142 Type Type
145 func (t *PtrType) String() string { return "*" + t.Type.String() }
147 // A StructType represents a struct, union, or C++ class type.
148 type StructType struct {
149 CommonType
150 StructName string
151 Kind string // "struct", "union", or "class".
152 Field []*StructField
153 Incomplete bool // if true, struct, union, class is declared but not defined
156 // A StructField represents a field in a struct, union, or C++ class type.
158 // Bit Fields
160 // The BitSize, BitOffset, and DataBitOffset fields describe the bit
161 // size and offset of data members declared as bit fields in C/C++
162 // struct/union/class types.
164 // BitSize is the number of bits in the bit field.
166 // DataBitOffset, if non-zero, is the number of bits from the start of
167 // the enclosing entity (e.g. containing struct/class/union) to the
168 // start of the bit field. This corresponds to the DW_AT_data_bit_offset
169 // DWARF attribute that was introduced in DWARF 4.
171 // BitOffset, if non-zero, is the number of bits between the most
172 // significant bit of the storage unit holding the bit field to the
173 // most significant bit of the bit field. Here "storage unit" is the
174 // type name before the bit field (for a field "unsigned x:17", the
175 // storage unit is "unsigned"). BitOffset values can vary depending on
176 // the endianness of the system. BitOffset corresponds to the
177 // DW_AT_bit_offset DWARF attribute that was deprecated in DWARF 4 and
178 // removed in DWARF 5.
180 // At most one of DataBitOffset and BitOffset will be non-zero;
181 // DataBitOffset/BitOffset will only be non-zero if BitSize is
182 // non-zero. Whether a C compiler uses one or the other
183 // will depend on compiler vintage and command line options.
185 // Here is an example of C/C++ bit field use, along with what to
186 // expect in terms of DWARF bit offset info. Consider this code:
188 // struct S {
189 // int q;
190 // int j:5;
191 // int k:6;
192 // int m:5;
193 // int n:8;
194 // } s;
196 // For the code above, one would expect to see the following for
197 // DW_AT_bit_offset values (using GCC 8):
199 // Little | Big
200 // Endian | Endian
201 // |
202 // "j": 27 | 0
203 // "k": 21 | 5
204 // "m": 16 | 11
205 // "n": 8 | 16
207 // Note that in the above the offsets are purely with respect to the
208 // containing storage unit for j/k/m/n -- these values won't vary based
209 // on the size of prior data members in the containing struct.
211 // If the compiler emits DW_AT_data_bit_offset, the expected values
212 // would be:
214 // "j": 32
215 // "k": 37
216 // "m": 43
217 // "n": 48
219 // Here the value 32 for "j" reflects the fact that the bit field is
220 // preceded by other data members (recall that DW_AT_data_bit_offset
221 // values are relative to the start of the containing struct). Hence
222 // DW_AT_data_bit_offset values can be quite large for structs with
223 // many fields.
225 // DWARF also allow for the possibility of base types that have
226 // non-zero bit size and bit offset, so this information is also
227 // captured for base types, but it is worth noting that it is not
228 // possible to trigger this behavior using mainstream languages.
230 type StructField struct {
231 Name string
232 Type Type
233 ByteOffset int64
234 ByteSize int64 // usually zero; use Type.Size() for normal fields
235 BitOffset int64
236 DataBitOffset int64
237 BitSize int64 // zero if not a bit field
240 func (t *StructType) String() string {
241 if t.StructName != "" {
242 return t.Kind + " " + t.StructName
244 return t.Defn()
247 func (f *StructField) bitOffset() int64 {
248 if f.BitOffset != 0 {
249 return f.BitOffset
251 return f.DataBitOffset
254 func (t *StructType) Defn() string {
255 s := t.Kind
256 if t.StructName != "" {
257 s += " " + t.StructName
259 if t.Incomplete {
260 s += " /*incomplete*/"
261 return s
263 s += " {"
264 for i, f := range t.Field {
265 if i > 0 {
266 s += "; "
268 s += f.Name + " " + f.Type.String()
269 s += "@" + strconv.FormatInt(f.ByteOffset, 10)
270 if f.BitSize > 0 {
271 s += " : " + strconv.FormatInt(f.BitSize, 10)
272 s += "@" + strconv.FormatInt(f.bitOffset(), 10)
275 s += "}"
276 return s
279 // An EnumType represents an enumerated type.
280 // The only indication of its native integer type is its ByteSize
281 // (inside CommonType).
282 type EnumType struct {
283 CommonType
284 EnumName string
285 Val []*EnumValue
288 // An EnumValue represents a single enumeration value.
289 type EnumValue struct {
290 Name string
291 Val int64
294 func (t *EnumType) String() string {
295 s := "enum"
296 if t.EnumName != "" {
297 s += " " + t.EnumName
299 s += " {"
300 for i, v := range t.Val {
301 if i > 0 {
302 s += "; "
304 s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
306 s += "}"
307 return s
310 // A FuncType represents a function type.
311 type FuncType struct {
312 CommonType
313 ReturnType Type
314 ParamType []Type
317 func (t *FuncType) String() string {
318 s := "func("
319 for i, t := range t.ParamType {
320 if i > 0 {
321 s += ", "
323 s += t.String()
325 s += ")"
326 if t.ReturnType != nil {
327 s += " " + t.ReturnType.String()
329 return s
332 // A DotDotDotType represents the variadic ... function parameter.
333 type DotDotDotType struct {
334 CommonType
337 func (t *DotDotDotType) String() string { return "..." }
339 // A TypedefType represents a named type.
340 type TypedefType struct {
341 CommonType
342 Type Type
345 func (t *TypedefType) String() string { return t.Name }
347 func (t *TypedefType) Size() int64 { return t.Type.Size() }
349 // An UnsupportedType is a placeholder returned in situations where we
350 // encounter a type that isn't supported.
351 type UnsupportedType struct {
352 CommonType
353 Tag Tag
356 func (t *UnsupportedType) String() string {
357 if t.Name != "" {
358 return t.Name
360 return t.Name + "(unsupported type " + t.Tag.String() + ")"
363 // typeReader is used to read from either the info section or the
364 // types section.
365 type typeReader interface {
366 Seek(Offset)
367 Next() (*Entry, error)
368 clone() typeReader
369 offset() Offset
370 // AddressSize returns the size in bytes of addresses in the current
371 // compilation unit.
372 AddressSize() int
375 // Type reads the type at off in the DWARF ``info'' section.
376 func (d *Data) Type(off Offset) (Type, error) {
377 return d.readType("info", d.Reader(), off, d.typeCache, nil)
380 type typeFixer struct {
381 typedefs []*TypedefType
382 arraytypes []*Type
385 func (tf *typeFixer) recordArrayType(t *Type) {
386 if t == nil {
387 return
389 _, ok := (*t).(*ArrayType)
390 if ok {
391 tf.arraytypes = append(tf.arraytypes, t)
395 func (tf *typeFixer) apply() {
396 for _, t := range tf.typedefs {
397 t.Common().ByteSize = t.Type.Size()
399 for _, t := range tf.arraytypes {
400 zeroArray(t)
404 // readType reads a type from r at off of name. It adds types to the
405 // type cache, appends new typedef types to typedefs, and computes the
406 // sizes of types. Callers should pass nil for typedefs; this is used
407 // for internal recursion.
408 func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type, fixups *typeFixer) (Type, error) {
409 if t, ok := typeCache[off]; ok {
410 return t, nil
412 r.Seek(off)
413 e, err := r.Next()
414 if err != nil {
415 return nil, err
417 addressSize := r.AddressSize()
418 if e == nil || e.Offset != off {
419 return nil, DecodeError{name, off, "no type at offset"}
422 // If this is the root of the recursion, prepare to resolve
423 // typedef sizes and perform other fixups once the recursion is
424 // done. This must be done after the type graph is constructed
425 // because it may need to resolve cycles in a different order than
426 // readType encounters them.
427 if fixups == nil {
428 var fixer typeFixer
429 defer func() {
430 fixer.apply()
432 fixups = &fixer
435 // Parse type from Entry.
436 // Must always set typeCache[off] before calling
437 // d.readType recursively, to handle circular types correctly.
438 var typ Type
440 nextDepth := 0
442 // Get next child; set err if error happens.
443 next := func() *Entry {
444 if !e.Children {
445 return nil
447 // Only return direct children.
448 // Skip over composite entries that happen to be nested
449 // inside this one. Most DWARF generators wouldn't generate
450 // such a thing, but clang does.
451 // See golang.org/issue/6472.
452 for {
453 kid, err1 := r.Next()
454 if err1 != nil {
455 err = err1
456 return nil
458 if kid == nil {
459 err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
460 return nil
462 if kid.Tag == 0 {
463 if nextDepth > 0 {
464 nextDepth--
465 continue
467 return nil
469 if kid.Children {
470 nextDepth++
472 if nextDepth > 0 {
473 continue
475 return kid
479 // Get Type referred to by Entry's AttrType field.
480 // Set err if error happens. Not having a type is an error.
481 typeOf := func(e *Entry) Type {
482 tval := e.Val(AttrType)
483 var t Type
484 switch toff := tval.(type) {
485 case Offset:
486 if t, err = d.readType(name, r.clone(), toff, typeCache, fixups); err != nil {
487 return nil
489 case uint64:
490 if t, err = d.sigToType(toff); err != nil {
491 return nil
493 default:
494 // It appears that no Type means "void".
495 return new(VoidType)
497 return t
500 switch e.Tag {
501 case TagArrayType:
502 // Multi-dimensional array. (DWARF v2 §5.4)
503 // Attributes:
504 // AttrType:subtype [required]
505 // AttrStrideSize: size in bits of each element of the array
506 // AttrByteSize: size of entire array
507 // Children:
508 // TagSubrangeType or TagEnumerationType giving one dimension.
509 // dimensions are in left to right order.
510 t := new(ArrayType)
511 typ = t
512 typeCache[off] = t
513 if t.Type = typeOf(e); err != nil {
514 goto Error
516 t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
518 // Accumulate dimensions,
519 var dims []int64
520 for kid := next(); kid != nil; kid = next() {
521 // TODO(rsc): Can also be TagEnumerationType
522 // but haven't seen that in the wild yet.
523 switch kid.Tag {
524 case TagSubrangeType:
525 count, ok := kid.Val(AttrCount).(int64)
526 if !ok {
527 // Old binaries may have an upper bound instead.
528 count, ok = kid.Val(AttrUpperBound).(int64)
529 if ok {
530 count++ // Length is one more than upper bound.
531 } else if len(dims) == 0 {
532 count = -1 // As in x[].
535 dims = append(dims, count)
536 case TagEnumerationType:
537 err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
538 goto Error
541 if len(dims) == 0 {
542 // LLVM generates this for x[].
543 dims = []int64{-1}
546 t.Count = dims[0]
547 for i := len(dims) - 1; i >= 1; i-- {
548 t.Type = &ArrayType{Type: t.Type, Count: dims[i]}
551 case TagBaseType:
552 // Basic type. (DWARF v2 §5.1)
553 // Attributes:
554 // AttrName: name of base type in programming language of the compilation unit [required]
555 // AttrEncoding: encoding value for type (encFloat etc) [required]
556 // AttrByteSize: size of type in bytes [required]
557 // AttrBitOffset: bit offset of value within containing storage unit
558 // AttrDataBitOffset: bit offset of value within containing storage unit
559 // AttrBitSize: size in bits
561 // For most languages BitOffset/DataBitOffset/BitSize will not be present
562 // for base types.
563 name, _ := e.Val(AttrName).(string)
564 enc, ok := e.Val(AttrEncoding).(int64)
565 if !ok {
566 err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
567 goto Error
569 switch enc {
570 default:
571 err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
572 goto Error
574 case encAddress:
575 typ = new(AddrType)
576 case encBoolean:
577 typ = new(BoolType)
578 case encComplexFloat:
579 typ = new(ComplexType)
580 if name == "complex" {
581 // clang writes out 'complex' instead of 'complex float' or 'complex double'.
582 // clang also writes out a byte size that we can use to distinguish.
583 // See issue 8694.
584 switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
585 case 8:
586 name = "complex float"
587 case 16:
588 name = "complex double"
591 case encFloat:
592 typ = new(FloatType)
593 case encSigned:
594 typ = new(IntType)
595 case encUnsigned:
596 typ = new(UintType)
597 case encSignedChar:
598 typ = new(CharType)
599 case encUnsignedChar:
600 typ = new(UcharType)
602 typeCache[off] = typ
603 t := typ.(interface {
604 Basic() *BasicType
605 }).Basic()
606 t.Name = name
607 t.BitSize, _ = e.Val(AttrBitSize).(int64)
608 haveBitOffset := false
609 haveDataBitOffset := false
610 t.BitOffset, haveBitOffset = e.Val(AttrBitOffset).(int64)
611 t.DataBitOffset, haveDataBitOffset = e.Val(AttrDataBitOffset).(int64)
612 if haveBitOffset && haveDataBitOffset {
613 err = DecodeError{name, e.Offset, "duplicate bit offset attributes"}
614 goto Error
617 case TagClassType, TagStructType, TagUnionType:
618 // Structure, union, or class type. (DWARF v2 §5.5)
619 // Attributes:
620 // AttrName: name of struct, union, or class
621 // AttrByteSize: byte size [required]
622 // AttrDeclaration: if true, struct/union/class is incomplete
623 // Children:
624 // TagMember to describe one member.
625 // AttrName: name of member [required]
626 // AttrType: type of member [required]
627 // AttrByteSize: size in bytes
628 // AttrBitOffset: bit offset within bytes for bit fields
629 // AttrDataBitOffset: field bit offset relative to struct start
630 // AttrBitSize: bit size for bit fields
631 // AttrDataMemberLoc: location within struct [required for struct, class]
632 // There is much more to handle C++, all ignored for now.
633 t := new(StructType)
634 typ = t
635 typeCache[off] = t
636 switch e.Tag {
637 case TagClassType:
638 t.Kind = "class"
639 case TagStructType:
640 t.Kind = "struct"
641 case TagUnionType:
642 t.Kind = "union"
644 t.StructName, _ = e.Val(AttrName).(string)
645 t.Incomplete = e.Val(AttrDeclaration) != nil
646 t.Field = make([]*StructField, 0, 8)
647 var lastFieldType *Type
648 var lastFieldBitSize int64
649 var lastFieldByteOffset int64
650 for kid := next(); kid != nil; kid = next() {
651 if kid.Tag != TagMember {
652 continue
654 f := new(StructField)
655 if f.Type = typeOf(kid); err != nil {
656 goto Error
658 switch loc := kid.Val(AttrDataMemberLoc).(type) {
659 case []byte:
660 // TODO: Should have original compilation
661 // unit here, not unknownFormat.
662 b := makeBuf(d, unknownFormat{}, "location", 0, loc)
663 if b.uint8() != opPlusUconst {
664 err = DecodeError{name, kid.Offset, "unexpected opcode"}
665 goto Error
667 f.ByteOffset = int64(b.uint())
668 if b.err != nil {
669 err = b.err
670 goto Error
672 case int64:
673 f.ByteOffset = loc
676 f.Name, _ = kid.Val(AttrName).(string)
677 f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
678 haveBitOffset := false
679 haveDataBitOffset := false
680 f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
681 f.DataBitOffset, haveDataBitOffset = kid.Val(AttrDataBitOffset).(int64)
682 if haveBitOffset && haveDataBitOffset {
683 err = DecodeError{name, e.Offset, "duplicate bit offset attributes"}
684 goto Error
686 f.BitSize, _ = kid.Val(AttrBitSize).(int64)
687 t.Field = append(t.Field, f)
689 if lastFieldBitSize == 0 && lastFieldByteOffset == f.ByteOffset && t.Kind != "union" {
690 // Last field was zero width. Fix array length.
691 // (DWARF writes out 0-length arrays as if they were 1-length arrays.)
692 fixups.recordArrayType(lastFieldType)
694 lastFieldType = &f.Type
695 lastFieldByteOffset = f.ByteOffset
696 lastFieldBitSize = f.BitSize
698 if t.Kind != "union" {
699 b, ok := e.Val(AttrByteSize).(int64)
700 if ok && b == lastFieldByteOffset {
701 // Final field must be zero width. Fix array length.
702 fixups.recordArrayType(lastFieldType)
706 case TagConstType, TagVolatileType, TagRestrictType:
707 // Type modifier (DWARF v2 §5.2)
708 // Attributes:
709 // AttrType: subtype
710 t := new(QualType)
711 typ = t
712 typeCache[off] = t
713 if t.Type = typeOf(e); err != nil {
714 goto Error
716 switch e.Tag {
717 case TagConstType:
718 t.Qual = "const"
719 case TagRestrictType:
720 t.Qual = "restrict"
721 case TagVolatileType:
722 t.Qual = "volatile"
725 case TagEnumerationType:
726 // Enumeration type (DWARF v2 §5.6)
727 // Attributes:
728 // AttrName: enum name if any
729 // AttrByteSize: bytes required to represent largest value
730 // Children:
731 // TagEnumerator:
732 // AttrName: name of constant
733 // AttrConstValue: value of constant
734 t := new(EnumType)
735 typ = t
736 typeCache[off] = t
737 t.EnumName, _ = e.Val(AttrName).(string)
738 t.Val = make([]*EnumValue, 0, 8)
739 for kid := next(); kid != nil; kid = next() {
740 if kid.Tag == TagEnumerator {
741 f := new(EnumValue)
742 f.Name, _ = kid.Val(AttrName).(string)
743 f.Val, _ = kid.Val(AttrConstValue).(int64)
744 n := len(t.Val)
745 if n >= cap(t.Val) {
746 val := make([]*EnumValue, n, n*2)
747 copy(val, t.Val)
748 t.Val = val
750 t.Val = t.Val[0 : n+1]
751 t.Val[n] = f
755 case TagPointerType:
756 // Type modifier (DWARF v2 §5.2)
757 // Attributes:
758 // AttrType: subtype [not required! void* has no AttrType]
759 // AttrAddrClass: address class [ignored]
760 t := new(PtrType)
761 typ = t
762 typeCache[off] = t
763 if e.Val(AttrType) == nil {
764 t.Type = &VoidType{}
765 break
767 t.Type = typeOf(e)
769 case TagSubroutineType:
770 // Subroutine type. (DWARF v2 §5.7)
771 // Attributes:
772 // AttrType: type of return value if any
773 // AttrName: possible name of type [ignored]
774 // AttrPrototyped: whether used ANSI C prototype [ignored]
775 // Children:
776 // TagFormalParameter: typed parameter
777 // AttrType: type of parameter
778 // TagUnspecifiedParameter: final ...
779 t := new(FuncType)
780 typ = t
781 typeCache[off] = t
782 if t.ReturnType = typeOf(e); err != nil {
783 goto Error
785 t.ParamType = make([]Type, 0, 8)
786 for kid := next(); kid != nil; kid = next() {
787 var tkid Type
788 switch kid.Tag {
789 default:
790 continue
791 case TagFormalParameter:
792 if tkid = typeOf(kid); err != nil {
793 goto Error
795 case TagUnspecifiedParameters:
796 tkid = &DotDotDotType{}
798 t.ParamType = append(t.ParamType, tkid)
801 case TagTypedef:
802 // Typedef (DWARF v2 §5.3)
803 // Attributes:
804 // AttrName: name [required]
805 // AttrType: type definition [required]
806 t := new(TypedefType)
807 typ = t
808 typeCache[off] = t
809 t.Name, _ = e.Val(AttrName).(string)
810 t.Type = typeOf(e)
812 case TagUnspecifiedType:
813 // Unspecified type (DWARF v3 §5.2)
814 // Attributes:
815 // AttrName: name
816 t := new(UnspecifiedType)
817 typ = t
818 typeCache[off] = t
819 t.Name, _ = e.Val(AttrName).(string)
821 default:
822 // This is some other type DIE that we're currently not
823 // equipped to handle. Return an abstract "unsupported type"
824 // object in such cases.
825 t := new(UnsupportedType)
826 typ = t
827 typeCache[off] = t
828 t.Tag = e.Tag
829 t.Name, _ = e.Val(AttrName).(string)
832 if err != nil {
833 goto Error
837 b, ok := e.Val(AttrByteSize).(int64)
838 if !ok {
839 b = -1
840 switch t := typ.(type) {
841 case *TypedefType:
842 // Record that we need to resolve this
843 // type's size once the type graph is
844 // constructed.
845 fixups.typedefs = append(fixups.typedefs, t)
846 case *PtrType:
847 b = int64(addressSize)
850 typ.Common().ByteSize = b
852 return typ, nil
854 Error:
855 // If the parse fails, take the type out of the cache
856 // so that the next call with this offset doesn't hit
857 // the cache and return success.
858 delete(typeCache, off)
859 return nil, err
862 func zeroArray(t *Type) {
863 at := (*t).(*ArrayType)
864 if at.Type.Size() == 0 {
865 return
867 // Make a copy to avoid invalidating typeCache.
868 tt := *at
869 tt.Count = 0
870 *t = &tt