func TypeSizeInBits(typ types.Type) int { switch typ := typ.(type) { case *types.Int: w := typ.Width() for w%8 != 0 { w++ } return w case *types.Float: return typ.Type().Width() case *types.Pointer: return 64 case *types.Array: return TypeSizeInBits(typ.Element()) * typ.Length() case *types.Struct: return newStructLayout(typ).size default: panic("unim") } }
// will always be multiple of 8 func TypeAlignmentInBits(typ types.Type) int { switch typ := typ.(type) { case *types.Struct: return newStructLayout(typ).alignment case *types.Array: return TypeAlignmentInBits(typ.Element()) } sz := TypeSizeInBits(typ) i := 8 for i < sz { i *= 2 } return i }
func checkTypeSupported(typ types.Type) { switch typ := typ.(type) { case *types.Int: switch typ.Width() { case 1, 8, 16, 32, 64: // all good default: goto unsupported } case *types.Array: checkTypeSupported(typ.Element()) case *types.Struct: for _, field := range typ.Fields() { checkTypeSupported(field) } } return unsupported: panic(fmt.Sprintf("unsupported type: %s", typ)) }