func needWrapType(typ types.Type) bool { switch typ := typ.(type) { case *types.Basic: return false case *types.Struct: return true case *types.Named: switch ut := typ.Underlying().(type) { case *types.Basic: return false default: return needWrapType(ut) } case *types.Array: return true case *types.Map: return true case *types.Slice: return true case *types.Interface: wrap := true if typ.Underlying() == universe.syms["error"].GoType().Underlying() { wrap = false } return wrap case *types.Signature: return true case *types.Pointer: return needWrapType(typ.Elem()) } return false }
func (f Field) UnderlyingTarget() fieldser { var t types.Type switch v := f.v.Type().(type) { case elemer: t = v.Elem() case *types.Named: t = v } if _, ok := t.(underlyinger); !ok { return nil } u := t.(underlyinger).Underlying() switch t := u.(type) { case *types.Struct: return fields{ g: f.gen, target: t, } case *types.Pointer: return fields{ g: f.gen, target: t.Elem().(*types.Named).Underlying().(*types.Struct), } } return nil }
// MethodSet returns the method set of type T. It is thread-safe. // // If cache is nil, this function is equivalent to types.NewMethodSet(T). // Utility functions can thus expose an optional *MethodSetCache // parameter to clients that care about performance. // func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { if cache == nil { return types.NewMethodSet(T) } cache.mu.Lock() defer cache.mu.Unlock() switch T := T.(type) { case *types.Named: return cache.lookupNamed(T).value case *types.Pointer: if N, ok := T.Elem().(*types.Named); ok { return cache.lookupNamed(N).pointer } } // all other types // (The map uses pointer equivalence, not type identity.) mset := cache.others[T] if mset == nil { mset = types.NewMethodSet(T) if cache.others == nil { cache.others = make(map[types.Type]*types.MethodSet) } cache.others[T] = mset } return mset }
// isSupported returns whether the generators can handle the type. func (g *generator) isSupported(t types.Type) bool { if isErrorType(t) { return true } switch t := t.(type) { case *types.Basic: return true case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: return e.Kind() == types.Uint8 } case *types.Pointer: switch t := t.Elem().(type) { case *types.Named: return g.validPkg(t.Obj().Pkg()) } case *types.Named: switch t.Underlying().(type) { case *types.Interface, *types.Pointer: return g.validPkg(t.Obj().Pkg()) } } return false }
// cgoType returns the name of a Cgo type suitable for converting a value of // the given type. func (g *generator) cgoType(t types.Type) string { if isErrorType(t) { return g.cgoType(types.Typ[types.String]) } switch t := t.(type) { case *types.Basic: switch t.Kind() { case types.Bool, types.UntypedBool: return "char" case types.Int: return "nint" case types.Int8: return "int8_t" case types.Int16: return "int16_t" case types.Int32, types.UntypedRune: // types.Rune return "int32_t" case types.Int64, types.UntypedInt: return "int64_t" case types.Uint8: // types.Byte return "uint8_t" // TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64: case types.Float32: return "float" case types.Float64, types.UntypedFloat: return "double" case types.String: return "nstring" default: g.errorf("unsupported basic type: %s", t) } case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. return "nbyteslice" default: g.errorf("unsupported slice type: %s", t) } default: g.errorf("unsupported slice type: %s", t) } case *types.Pointer: if _, ok := t.Elem().(*types.Named); ok { return g.cgoType(t.Elem()) } g.errorf("unsupported pointer to type: %s", t) case *types.Named: return "int32_t" default: g.errorf("unsupported type: %s", t) } return "TODO" }
func (g *goGen) genWrite(toVar, fromVar string, t types.Type, mode varMode) { if isErrorType(t) { g.Printf("var %s_str string\n", toVar) g.Printf("if %s == nil {\n", fromVar) g.Printf(" %s_str = \"\"\n", toVar) g.Printf("} else {\n") g.Printf(" %s_str = %s.Error()\n", toVar, fromVar) g.Printf("}\n") g.genWrite(toVar, toVar+"_str", types.Typ[types.String], mode) return } switch t := t.(type) { case *types.Basic: switch t.Kind() { case types.String: g.Printf("%s := encodeString(%s)\n", toVar, fromVar) case types.Bool: g.Printf("var %s C.%s = 0\n", toVar, g.cgoType(t)) g.Printf("if %s { %s = 1 }\n", fromVar, toVar) default: g.Printf("%s := C.%s(%s)\n", toVar, g.cgoType(t), fromVar) } case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. g.Printf("%s := fromSlice(%s, %v)\n", toVar, fromVar, mode == modeRetained) default: g.errorf("unsupported type: %s", t) } default: g.errorf("unsupported type: %s", t) } case *types.Pointer: // TODO(crawshaw): test *int // TODO(crawshaw): test **Generator switch t := t.Elem().(type) { case *types.Named: g.genToRefNum(toVar, fromVar) default: g.errorf("unsupported type %s", t) } case *types.Named: switch u := t.Underlying().(type) { case *types.Interface, *types.Pointer: g.genToRefNum(toVar, fromVar) default: g.errorf("unsupported, direct named type %s: %s", t, u) } default: g.errorf("unsupported type %s", t) } }
// jniType returns a string that can be used as a JNI type. func (g *javaGen) jniType(T types.Type) string { if isErrorType(T) { // The error type is usually translated into an exception in // Java, however the type can be exposed in other ways, such // as an exported field. return g.jniType(types.Typ[types.String]) } switch T := T.(type) { case *types.Basic: switch T.Kind() { case types.Bool, types.UntypedBool: return "jboolean" case types.Int: return "jlong" case types.Int8: return "jbyte" case types.Int16: return "jshort" case types.Int32, types.UntypedRune: // types.Rune return "jint" case types.Int64, types.UntypedInt: return "jlong" case types.Uint8: // types.Byte // TODO(crawshaw): Java bytes are signed, so this is // questionable, but vital. return "jbyte" // TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64: case types.Float32: return "jfloat" case types.Float64, types.UntypedFloat: return "jdouble" case types.String, types.UntypedString: return "jstring" default: g.errorf("unsupported basic type: %s", T) return "TODO" } case *types.Slice: return "jbyteArray" case *types.Pointer: if _, ok := T.Elem().(*types.Named); ok { return g.jniType(T.Elem()) } g.errorf("unsupported pointer to type: %s", T) case *types.Named: return "jobject" default: g.errorf("unsupported jniType: %#+v, %s\n", T, T) } return "TODO" }
func isExported(t types.Type) bool { if isErrorType(t) { return true } switch t := t.(type) { case *types.Basic: return true case *types.Named: return t.Obj().Exported() case *types.Pointer: return isExported(t.Elem()) default: return true } }
func (g *goGen) genWrite(valName, seqName string, T types.Type) { if isErrorType(T) { g.Printf("if %s == nil {\n", valName) g.Printf(" %s.WriteString(\"\");\n", seqName) g.Printf("} else {\n") g.Printf(" %s.WriteString(%s.Error());\n", seqName, valName) g.Printf("}\n") return } switch T := T.(type) { case *types.Pointer: // TODO(crawshaw): test *int // TODO(crawshaw): test **Generator switch T := T.Elem().(type) { case *types.Named: obj := T.Obj() if obj.Pkg() != g.pkg { g.errorf("type %s not defined in package %s", T, g.pkg) return } g.Printf("%s.WriteGoRef(%s)\n", seqName, valName) default: g.errorf("unsupported type %s", T) } case *types.Named: switch u := T.Underlying().(type) { case *types.Interface, *types.Pointer: g.Printf("%s.WriteGoRef(%s)\n", seqName, valName) default: g.errorf("unsupported, direct named type %s: %s", T, u) } default: g.Printf("%s.Write%s(%s);\n", seqName, seqType(T), valName) } }
func (g *javaGen) genRead(resName, seqName string, T types.Type) { switch T := T.(type) { case *types.Pointer: // TODO(crawshaw): test *int // TODO(crawshaw): test **Generator switch T := T.Elem().(type) { case *types.Named: o := T.Obj() if o.Pkg() != g.pkg { g.errorf("type %s not defined in %s", T, g.pkg) return } g.Printf("%s = new %s(%s.readRef());\n", resName, o.Name(), seqName) default: g.errorf("unsupported type %s", T) } case *types.Named: switch T.Underlying().(type) { case *types.Interface, *types.Pointer: o := T.Obj() if o.Pkg() != g.pkg { g.errorf("type %s not defined in %s", T, g.pkg) return } g.Printf("%s = new %s.Proxy(%s.readRef());\n", resName, o.Name(), seqName) default: g.errorf("unsupported, direct named type %s", T) } default: g.Printf("%s = %s.read%s();\n", resName, seqName, seqType(T)) } }
func (g *ObjcGen) genWrite(varName string, t types.Type, mode varMode) { switch t := t.(type) { case *types.Basic: switch t.Kind() { case types.String: g.Printf("nstring _%s = go_seq_from_objc_string(%s);\n", varName, varName) default: g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName) } case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. g.Printf("nbyteslice _%s = go_seq_from_objc_bytearray(%s, %d);\n", varName, varName, toCFlag(mode == modeRetained)) default: g.errorf("unsupported type: %s", t) } default: g.errorf("unsupported type: %s", t) } case *types.Named: switch u := t.Underlying().(type) { case *types.Interface: g.genRefWrite(varName) default: g.errorf("unsupported named type: %s / %T", u, u) } case *types.Pointer: g.genRefWrite(varName) default: g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName) } }
func (g *javaGen) genCToJava(toName, fromName string, t types.Type, mode varMode) { if isErrorType(t) { g.genCToJava(toName, fromName, types.Typ[types.String], mode) return } switch t := t.(type) { case *types.Basic: switch t.Kind() { case types.String: g.Printf("jstring %s = go_seq_to_java_string(env, %s);\n", toName, fromName) case types.Bool: g.Printf("jboolean %s = %s ? JNI_TRUE : JNI_FALSE;\n", toName, fromName) default: g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName) } case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. g.Printf("jbyteArray %s = go_seq_to_java_bytearray(env, %s, %d);\n", toName, fromName, g.toCFlag(mode == modeRetained)) default: g.errorf("unsupported type: %s", t) } default: g.errorf("unsupported type: %s", t) } case *types.Pointer: // TODO(crawshaw): test *int // TODO(crawshaw): test **Generator switch t := t.Elem().(type) { case *types.Named: g.genFromRefnum(toName, fromName, t, t.Obj()) default: g.errorf("unsupported type %s", t) } case *types.Named: switch t.Underlying().(type) { case *types.Interface, *types.Pointer: g.genFromRefnum(toName, fromName, t, t.Obj()) default: g.errorf("unsupported, direct named type %s", t) } default: g.Printf("%s %s = (%s)%s;\n", g.jniType(t), toName, g.jniType(t), fromName) } }
// jniType returns a string that can be used as a JNI type. func (g *JavaGen) jniType(T types.Type) string { switch T := T.(type) { case *types.Basic: switch T.Kind() { case types.Bool, types.UntypedBool: return "jboolean" case types.Int: return "jlong" case types.Int8: return "jbyte" case types.Int16: return "jshort" case types.Int32, types.UntypedRune: // types.Rune return "jint" case types.Int64, types.UntypedInt: return "jlong" case types.Uint8: // types.Byte // TODO(crawshaw): Java bytes are signed, so this is // questionable, but vital. return "jbyte" // TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64: case types.Float32: return "jfloat" case types.Float64, types.UntypedFloat: return "jdouble" case types.String, types.UntypedString: return "jstring" default: g.errorf("unsupported basic type: %s", T) return "TODO" } case *types.Slice: return "jbyteArray" case *types.Pointer: if _, ok := T.Elem().(*types.Named); ok { return g.jniType(T.Elem()) } g.errorf("unsupported pointer to type: %s", T) case *types.Named: return "jobject" default: g.errorf("unsupported jniType: %#+v, %s\n", T, T) } return "TODO" }
func (g *objcGen) genRead(toName, fromName string, t types.Type, mode varMode) { if isErrorType(t) { g.genRead(toName, fromName, types.Typ[types.String], mode) return } switch t := t.(type) { case *types.Basic: switch t.Kind() { case types.String: g.Printf("NSString *%s = go_seq_to_objc_string(%s);\n", toName, fromName) case types.Bool: g.Printf("BOOL %s = %s ? YES : NO;\n", toName, fromName) default: g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName) } case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. g.Printf("NSData *%s = go_seq_to_objc_bytearray(%s, %d);\n", toName, fromName, g.toCFlag(mode == modeRetained)) default: g.errorf("unsupported type: %s", t) } default: g.errorf("unsupported type: %s", t) } case *types.Pointer: switch t := t.Elem().(type) { case *types.Named: g.genRefRead(toName, fromName, types.NewPointer(t)) default: g.errorf("unsupported type %s", t) } case *types.Named: switch t.Underlying().(type) { case *types.Interface, *types.Pointer: g.genRefRead(toName, fromName, t) default: g.errorf("unsupported, direct named type %s", t) } default: g.Printf("%s %s = (%s)%s;\n", g.objcType(t), toName, g.objcType(t), fromName) } }
// store stores value v of type T into *addr. func store(T types.Type, addr *value, v value) { switch T := T.Underlying().(type) { case *types.Struct: lhs := (*addr).(structure) rhs := v.(structure) for i := range lhs { store(T.Field(i).Type(), &lhs[i], rhs[i]) } case *types.Array: lhs := (*addr).(array) rhs := v.(array) for i := range lhs { store(T.Elem(), &lhs[i], rhs[i]) } default: *addr = v } }
func isRefType(t types.Type) bool { if isErrorType(t) { return false } switch t := t.(type) { case *types.Named: switch u := t.Underlying().(type) { case *types.Interface: return true default: panic(fmt.Sprintf("unsupported named type: %s / %T", u, u)) } case *types.Pointer: return isRefType(t.Elem()) default: return false } }
func (g *objcGen) refTypeBase(typ types.Type) string { switch typ := typ.(type) { case *types.Pointer: if _, ok := typ.Elem().(*types.Named); ok { return g.objcType(typ.Elem()) } case *types.Named: n := typ.Obj() if n.Pkg() == g.pkg { switch typ.Underlying().(type) { case *types.Interface, *types.Struct: return g.namePrefix + n.Name() } } } // fallback to whatever objcType returns. This must not happen. return g.objcType(typ) }
func (g *javaGen) jniCallType(t types.Type) string { if isErrorType(t) { return g.jniCallType(types.Typ[types.String]) } switch t := t.(type) { case *types.Basic: switch t.Kind() { case types.Bool, types.UntypedBool: return "Boolean" case types.Int: return "Long" case types.Int8, types.Uint8: // types.Byte return "Byte" case types.Int16: return "Short" case types.Int32, types.UntypedRune: // types.Rune return "Int" case types.Int64, types.UntypedInt: return "Long" case types.Float32: return "Float" case types.Float64, types.UntypedFloat: return "Double" case types.String, types.UntypedString: return "Object" default: g.errorf("unsupported basic type: %s", t) } case *types.Slice: return "Object" case *types.Pointer: if _, ok := t.Elem().(*types.Named); ok { return g.jniCallType(t.Elem()) } g.errorf("unsupported pointer to type: %s", t) case *types.Named: return "Object" default: return "Object" } return "TODO" }
// load returns the value of type T in *addr. func load(T types.Type, addr *value) value { switch T := T.Underlying().(type) { case *types.Struct: v := (*addr).(structure) a := make(structure, len(v)) for i := range a { a[i] = load(T.Field(i).Type(), &v[i]) } return a case *types.Array: v := (*addr).(array) a := make(array, len(v)) for i := range a { a[i] = load(T.Elem(), &v[i]) } return a default: return *addr } }
// typeOKForCgoCall returns true if the type of arg is OK to pass to a // C function using cgo. This is not true for Go types with embedded // pointers. func typeOKForCgoCall(t types.Type) bool { if t == nil { return true } switch t := t.Underlying().(type) { case *types.Chan, *types.Map, *types.Signature, *types.Slice: return false case *types.Pointer: return typeOKForCgoCall(t.Elem()) case *types.Array: return typeOKForCgoCall(t.Elem()) case *types.Struct: for i := 0; i < t.NumFields(); i++ { if !typeOKForCgoCall(t.Field(i).Type()) { return false } } } return true }
func (g *ObjcGen) refTypeBase(typ types.Type) string { switch typ := typ.(type) { case *types.Pointer: if _, ok := typ.Elem().(*types.Named); ok { return g.objcType(typ.Elem()) } case *types.Named: n := typ.Obj() if isObjcType(typ) { return g.wrapMap[n.Name()].Name } if isErrorType(typ) || g.validPkg(n.Pkg()) { switch typ.Underlying().(type) { case *types.Interface, *types.Struct: return g.namePrefixOf(n.Pkg()) + n.Name() } } } // fallback to whatever objcType returns. This must not happen. return g.objcType(typ) }
// genRelease cleans up arguments that weren't copied in genJavaToC. func (g *JavaGen) genRelease(varName string, t types.Type, mode varMode) { switch t := t.(type) { case *types.Basic: case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. if mode == modeTransient { g.Printf("go_seq_release_byte_array(env, %s, _%s.ptr);\n", varName, varName) } } } } }
// javaType returns a string that can be used as a Java type. func (g *javaGen) javaType(T types.Type) string { switch T := T.(type) { case *types.Basic: switch T.Kind() { case types.Bool: return "boolean" case types.Int: return "long" case types.Int8: return "byte" case types.Int16: return "short" case types.Int32: return "int" case types.Int64: return "long" case types.Uint8: // TODO(crawshaw): Java bytes are signed, so this is // questionable, but vital. return "byte" // TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64: case types.Float32: return "float" case types.Float64: return "double" case types.String: return "String" default: g.errorf("unsupported return type: %s", T) return "TODO" } case *types.Slice: elem := g.javaType(T.Elem()) return elem + "[]" case *types.Pointer: if _, ok := T.Elem().(*types.Named); ok { return g.javaType(T.Elem()) } panic(fmt.Sprintf("unsupporter pointer to type: %s", T)) case *types.Named: n := T.Obj() if n.Pkg() != g.pkg { panic(fmt.Sprintf("type %s is in package %s, must be defined in package %s", n.Name(), n.Pkg().Name(), g.pkg.Name())) } // TODO(crawshaw): more checking here return n.Name() default: g.errorf("unsupported javaType: %#+v, %s\n", T, T) return "TODO" } }
// genRelease cleans up arguments that weren't copied in genWrite. func (g *ObjcGen) genRelease(varName string, t types.Type, mode varMode) { switch t := t.(type) { case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. if mode == modeTransient { // If the argument was not mutable, go_seq_from_objc_bytearray created a copy. // Free it here. g.Printf("if (![%s isKindOfClass:[NSMutableData class]]) {\n", varName) g.Printf(" free(_%s.ptr);\n", varName) g.Printf("}\n") } } } } }
// genRelease cleans up arguments that weren't copied in genJavaToC. func (g *javaGen) genRelease(varName string, t types.Type, mode varMode) { if isErrorType(t) { g.genRelease(varName, types.Typ[types.String], mode) return } switch t := t.(type) { case *types.Basic: case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. if mode == modeTransient { g.Printf("if (_%s.ptr != NULL) {\n", varName) g.Printf(" (*env)->ReleaseByteArrayElements(env, %s, _%s.ptr, 0);\n", varName, varName) g.Printf("}\n") } } } } }
func (g *javaGen) genJavaToC(varName string, t types.Type, mode varMode) { if isErrorType(t) { g.genJavaToC(varName, types.Typ[types.String], mode) return } switch t := t.(type) { case *types.Basic: switch t.Kind() { case types.String: g.Printf("nstring _%s = go_seq_from_java_string(env, %s);\n", varName, varName) default: g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName) } case *types.Slice: switch e := t.Elem().(type) { case *types.Basic: switch e.Kind() { case types.Uint8: // Byte. g.Printf("nbyteslice _%s = go_seq_from_java_bytearray(env, %s, %d);\n", varName, varName, g.toCFlag(mode == modeRetained)) default: g.errorf("unsupported type: %s", t) } default: g.errorf("unsupported type: %s", t) } case *types.Named: switch u := t.Underlying().(type) { case *types.Interface: g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName) default: g.errorf("unsupported named type: %s / %T", u, u) } case *types.Pointer: g.Printf("int32_t _%s = go_seq_to_refnum(env, %s);\n", varName, varName) default: g.Printf("%s _%s = (%s)%s;\n", g.cgoType(t), varName, g.cgoType(t), varName) } }
func (g *javaGen) jniSigType(T types.Type) string { if isErrorType(T) { return g.jniSigType(types.Typ[types.String]) } switch T := T.(type) { case *types.Basic: switch T.Kind() { case types.Bool, types.UntypedBool: return "Z" case types.Int: return "J" case types.Int8: return "B" case types.Int16: return "S" case types.Int32, types.UntypedRune: // types.Rune return "I" case types.Int64, types.UntypedInt: return "J" case types.Uint8: // types.Byte return "B" case types.Float32: return "F" case types.Float64, types.UntypedFloat: return "D" case types.String, types.UntypedString: return "Ljava/lang/String;" default: g.errorf("unsupported basic type: %s", T) return "TODO" } case *types.Slice: return "[" + g.jniSigType(T.Elem()) case *types.Pointer: if _, ok := T.Elem().(*types.Named); ok { return g.jniSigType(T.Elem()) } g.errorf("unsupported pointer to type: %s", T) case *types.Named: return "L" + g.jniClassSigPrefix(T.Obj().Pkg()) + T.Obj().Name() + ";" default: g.errorf("unsupported jniType: %#+v, %s\n", T, T) } return "TODO" }
// javaType returns a string that can be used as a Java type. func (g *JavaGen) javaType(T types.Type) string { if isErrorType(T) { // The error type is usually translated into an exception in // Java, however the type can be exposed in other ways, such // as an exported field. return "java.lang.Exception" } else if isJavaType(T) { return classNameFor(T) } switch T := T.(type) { case *types.Basic: return g.javaBasicType(T) case *types.Slice: elem := g.javaType(T.Elem()) return elem + "[]" case *types.Pointer: if _, ok := T.Elem().(*types.Named); ok { return g.javaType(T.Elem()) } g.errorf("unsupported pointer to type: %s", T) case *types.Named: n := T.Obj() nPkg := n.Pkg() if !isErrorType(T) && !g.validPkg(nPkg) { g.errorf("type %s is in %s, which is not bound", n.Name(), nPkg) break } // TODO(crawshaw): more checking here if nPkg != g.Pkg { return fmt.Sprintf("%s.%s", g.javaPkgName(nPkg), n.Name()) } else { return n.Name() } default: g.errorf("unsupported javaType: %#+v, %s\n", T, T) } return "TODO" }
func (f *File) validParamType(typ types.Type) *Error { if e := f.validVarDeclType(typ); e != nil { switch typ.(type) { default: return e case *types.Pointer: typ := typ.(*types.Pointer) return f.validParamType(typ.Elem()) case *types.Slice: typ := typ.(*types.Slice) return f.validParamType(typ.Elem()) case *types.Array: typ := typ.(*types.Array) return f.validParamType(typ.Elem()) case *types.Named: /*named, ok := typ.(*types.Named) if !ok { panic("ERROR can't cast to named type") } tname := named.Obj() i := Int(0) var i4 Int4 ivar := &i simdIntVar := reflect.TypeOf(ivar) i4var := &i4 simdInt4Var := reflect.TypeOf(i4var)*/ /*switch tname.Name() { default: return e case simdIntVar.Name(): return nil case simdInt4Var.Name(): return nil }*/ return e } } return nil }
func (p *exporter) typ(t types.Type) { if t == nil { log.Fatalf("gcimporter: nil type") } // Possible optimization: Anonymous pointer types *T where // T is a named type are common. We could canonicalize all // such types *T to a single type PT = *T. This would lead // to at most one *T entry in typIndex, and all future *T's // would be encoded as the respective index directly. Would // save 1 byte (pointerTag) per *T and reduce the typIndex // size (at the cost of a canonicalization map). We can do // this later, without encoding format change. // if we saw the type before, write its index (>= 0) if i, ok := p.typIndex[t]; ok { p.index('T', i) return } // otherwise, remember the type, write the type tag (< 0) and type data if trackAllTypes { if trace { p.tracef("T%d = {>\n", len(p.typIndex)) defer p.tracef("<\n} ") } p.typIndex[t] = len(p.typIndex) } switch t := t.(type) { case *types.Named: if !trackAllTypes { // if we don't track all types, track named types now p.typIndex[t] = len(p.typIndex) } p.tag(namedTag) p.pos(t.Obj()) p.qualifiedName(t.Obj()) p.typ(t.Underlying()) if !types.IsInterface(t) { p.assocMethods(t) } case *types.Array: p.tag(arrayTag) p.int64(t.Len()) p.typ(t.Elem()) case *types.Slice: p.tag(sliceTag) p.typ(t.Elem()) case *dddSlice: p.tag(dddTag) p.typ(t.elem) case *types.Struct: p.tag(structTag) p.fieldList(t) case *types.Pointer: p.tag(pointerTag) p.typ(t.Elem()) case *types.Signature: p.tag(signatureTag) p.paramList(t.Params(), t.Variadic()) p.paramList(t.Results(), false) case *types.Interface: p.tag(interfaceTag) p.iface(t) case *types.Map: p.tag(mapTag) p.typ(t.Key()) p.typ(t.Elem()) case *types.Chan: p.tag(chanTag) p.int(int(3 - t.Dir())) // hack p.typ(t.Elem()) default: log.Fatalf("gcimporter: unexpected type %T: %s", t, t) } }