1 // Copyright 2013 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 // Package gcsizes provides a types.Sizes implementation that adheres
6 // to the rules used by the gc compiler.
7 package gcsizes // import "honnef.co/go/tools/gcsizes"
19 // ForArch returns a correct Sizes for the given architecture.
20 func ForArch(arch string) *Sizes {
23 switch build.Default.GOARCH {
25 wordSize, maxAlign = 4, 4
29 return &Sizes{WordSize: wordSize, MaxAlign: maxAlign}
32 func (s *Sizes) Alignof(T types.Type) int64 {
33 switch t := T.Underlying().(type) {
35 return s.Alignof(t.Elem())
39 var fields []*types.Var
40 for i := 0; i < n; i++ {
41 fields = append(fields, t.Field(i))
43 for _, f := range fields {
44 if a := s.Alignof(f.Type()); a > max {
50 a := s.Sizeof(T) // may be 0
60 func (s *Sizes) Offsetsof(fields []*types.Var) []int64 {
61 offsets := make([]int64, len(fields))
63 for i, f := range fields {
64 a := s.Alignof(f.Type())
67 o += s.Sizeof(f.Type())
72 var basicSizes = [...]byte{
88 func (s *Sizes) Sizeof(T types.Type) int64 {
89 switch t := T.Underlying().(type) {
92 if int(k) < len(basicSizes) {
93 if s := basicSizes[k]; s > 0 {
97 if k == types.String {
105 a := s.Alignof(t.Elem())
106 z := s.Sizeof(t.Elem())
107 return align(z, a)*(n-1) + z
109 return s.WordSize * 3
116 var fields []*types.Var
117 for i := 0; i < n; i++ {
118 fields = append(fields, t.Field(i))
120 offsets := s.Offsetsof(fields)
122 lsz := s.Sizeof(fields[n-1].Type())
126 z := offsets[n-1] + lsz
128 case *types.Interface:
129 return s.WordSize * 2
131 return s.WordSize // catch-all
134 // align returns the smallest y >= x such that y % a == 0.
135 func align(x, a int64) int64 {