// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.

// Copyright 2023 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 types

type gcSizes struct {
	WordSize int64 // word size in bytes - must be >= 4 (32bits)
	MaxAlign int64 // maximum alignment in bytes - must be >= 1
}

func ( *gcSizes) ( Type) ( int64) {
	defer func() {
		assert( >= 1)
	}()

	// For arrays and structs, alignment is defined in terms
	// of alignment of the elements and fields, respectively.
	switch t := under().(type) {
	case *Array:
		// spec: "For a variable x of array type: unsafe.Alignof(x)
		// is the same as unsafe.Alignof(x[0]), but at least 1."
		return .(.elem)
	case *Struct:
		if len(.fields) == 0 && _IsSyncAtomicAlign64() {
			// Special case: sync/atomic.align64 is an
			// empty struct we recognize as a signal that
			// the struct it contains must be
			// 64-bit-aligned.
			//
			// This logic is equivalent to the logic in
			// cmd/compile/internal/types/size.go:calcStructOffset
			return 8
		}

		// spec: "For a variable x of struct type: unsafe.Alignof(x)
		// is the largest of the values unsafe.Alignof(x.f) for each
		// field f of x, but at least 1."
		 := int64(1)
		for ,  := range .fields {
			if  := .(.typ);  >  {
				 = 
			}
		}
		return 
	case *Slice, *Interface:
		// Multiword data structures are effectively structs
		// in which each element has size WordSize.
		// Type parameters lead to variable sizes/alignments;
		// StdSizes.Alignof won't be called for them.
		assert(!isTypeParam())
		return .WordSize
	case *Basic:
		// Strings are like slices and interfaces.
		if .Info()&IsString != 0 {
			return .WordSize
		}
	case *TypeParam, *Union:
		unreachable()
	}
	 := .Sizeof() // may be 0 or negative
	// spec: "For a variable x of any type: unsafe.Alignof(x) is at least 1."
	if  < 1 {
		return 1
	}
	// complex{64,128} are aligned like [2]float{32,64}.
	if isComplex() {
		 /= 2
	}
	if  > .MaxAlign {
		return .MaxAlign
	}
	return 
}

func ( *gcSizes) ( []*Var) []int64 {
	 := make([]int64, len())
	var  int64
	for ,  := range  {
		if  < 0 {
			// all remaining offsets are too large
			[] = -1
			continue
		}
		// offs >= 0
		 := .Alignof(.typ)
		 = align(, ) // possibly < 0 if align overflows
		[] = 
		if  := .Sizeof(.typ);  >= 0 &&  >= 0 {
			 +=  // ok to overflow to < 0
		} else {
			 = -1 // f.typ or offs is too large
		}
	}
	return 
}

func ( *gcSizes) ( Type) int64 {
	switch t := under().(type) {
	case *Basic:
		assert(isTyped())
		 := .kind
		if int() < len(basicSizes) {
			if  := basicSizes[];  > 0 {
				return int64()
			}
		}
		if  == String {
			return .WordSize * 2
		}
	case *Array:
		 := .len
		if  <= 0 {
			return 0
		}
		// n > 0
		 := .(.elem)
		if  < 0 {
			return -1 // element too large
		}
		if  == 0 {
			return 0 // 0-size element
		}
		// esize > 0
		// Final size is esize * n; and size must be <= maxInt64.
		const  = 1<<63 - 1
		if  > / {
			return -1 // esize * n overflows
		}
		return  * 
	case *Slice:
		return .WordSize * 3
	case *Struct:
		 := .NumFields()
		if  == 0 {
			return 0
		}
		 := .Offsetsof(.fields)
		 := [-1]
		 := .(.fields[-1].typ)
		if  < 0 ||  < 0 {
			return -1 // type too large
		}
		// gc: The last field of a non-zero-sized struct is not allowed to
		// have size 0.
		if  > 0 &&  == 0 {
			 = 1
		}
		// gc: Size includes alignment padding.
		return align(+, .Alignof()) // may overflow to < 0 which is ok
	case *Interface:
		// Type parameters lead to variable sizes/alignments;
		// StdSizes.Sizeof won't be called for them.
		assert(!isTypeParam())
		return .WordSize * 2
	case *TypeParam, *Union:
		unreachable()
	}
	return .WordSize // catch-all
}

// gcSizesFor returns the Sizes used by gc for an architecture.
// The result is a nil *gcSizes pointer (which is not a valid types.Sizes)
// if a compiler/architecture pair is not known.
func gcSizesFor(,  string) *gcSizes {
	if  != "gc" {
		return nil
	}
	return gcArchSizes[]
}