.gitignore added
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / honnef.co / go / tools@v0.1.1 / go / gcsizes / sizes.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.1.1/go/gcsizes/sizes.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/honnef.co/go/tools@v0.1.1/go/gcsizes/sizes.go
new file mode 100644 (file)
index 0000000..d6bbf47
--- /dev/null
@@ -0,0 +1,138 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gcsizes provides a types.Sizes implementation that adheres
+// to the rules used by the gc compiler.
+package gcsizes
+
+import (
+       "go/build"
+       "go/types"
+)
+
+type Sizes struct {
+       WordSize int64
+       MaxAlign int64
+}
+
+// ForArch returns a correct Sizes for the given architecture.
+func ForArch(arch string) *Sizes {
+       wordSize := int64(8)
+       maxAlign := int64(8)
+       switch build.Default.GOARCH {
+       case "386", "arm":
+               wordSize, maxAlign = 4, 4
+       case "amd64p32":
+               wordSize = 4
+       }
+       return &Sizes{WordSize: wordSize, MaxAlign: maxAlign}
+}
+
+func (s *Sizes) Alignof(T types.Type) int64 {
+       switch t := T.Underlying().(type) {
+       case *types.Array:
+               return s.Alignof(t.Elem())
+       case *types.Struct:
+               max := int64(1)
+               n := t.NumFields()
+               var fields []*types.Var
+               for i := 0; i < n; i++ {
+                       fields = append(fields, t.Field(i))
+               }
+               for _, f := range fields {
+                       if a := s.Alignof(f.Type()); a > max {
+                               max = a
+                       }
+               }
+               return max
+       }
+       a := s.Sizeof(T) // may be 0
+       if a < 1 {
+               return 1
+       }
+       if a > s.MaxAlign {
+               return s.MaxAlign
+       }
+       return a
+}
+
+func (s *Sizes) Offsetsof(fields []*types.Var) []int64 {
+       offsets := make([]int64, len(fields))
+       var o int64
+       for i, f := range fields {
+               a := s.Alignof(f.Type())
+               o = align(o, a)
+               offsets[i] = o
+               o += s.Sizeof(f.Type())
+       }
+       return offsets
+}
+
+var basicSizes = [...]byte{
+       types.Bool:       1,
+       types.Int8:       1,
+       types.Int16:      2,
+       types.Int32:      4,
+       types.Int64:      8,
+       types.Uint8:      1,
+       types.Uint16:     2,
+       types.Uint32:     4,
+       types.Uint64:     8,
+       types.Float32:    4,
+       types.Float64:    8,
+       types.Complex64:  8,
+       types.Complex128: 16,
+}
+
+func (s *Sizes) Sizeof(T types.Type) int64 {
+       switch t := T.Underlying().(type) {
+       case *types.Basic:
+               k := t.Kind()
+               if int(k) < len(basicSizes) {
+                       if s := basicSizes[k]; s > 0 {
+                               return int64(s)
+                       }
+               }
+               if k == types.String {
+                       return s.WordSize * 2
+               }
+       case *types.Array:
+               n := t.Len()
+               if n == 0 {
+                       return 0
+               }
+               a := s.Alignof(t.Elem())
+               z := s.Sizeof(t.Elem())
+               return align(z, a)*(n-1) + z
+       case *types.Slice:
+               return s.WordSize * 3
+       case *types.Struct:
+               n := t.NumFields()
+               if n == 0 {
+                       return 0
+               }
+
+               var fields []*types.Var
+               for i := 0; i < n; i++ {
+                       fields = append(fields, t.Field(i))
+               }
+               offsets := s.Offsetsof(fields)
+               a := s.Alignof(T)
+               lsz := s.Sizeof(fields[n-1].Type())
+               if lsz == 0 {
+                       lsz = 1
+               }
+               z := offsets[n-1] + lsz
+               return align(z, a)
+       case *types.Interface:
+               return s.WordSize * 2
+       }
+       return s.WordSize // catch-all
+}
+
+// align returns the smallest y >= x such that y % a == 0.
+func align(x, a int64) int64 {
+       y := x + a - 1
+       return y - y%a
+}