From 22f89bf9a45c50837f00a5d4a51946f86dbe13c2 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 18 May 2024 19:04:04 +0800 Subject: [PATCH 1/2] remove c2go support --- ast.go | 4 +-- builtin_test.go | 67 ++-------------------------------- c.go | 27 ++++++++++++++ c_test.go | 3 +- codebuild.go | 23 ------------ cpackages/import.go | 86 -------------------------------------------- cpackages/pubfile.go | 79 ---------------------------------------- type_ext.go | 15 +------- 8 files changed, 34 insertions(+), 270 deletions(-) delete mode 100644 cpackages/import.go delete mode 100644 cpackages/pubfile.go diff --git a/ast.go b/ast.go index bceb6f63..86f60187 100644 --- a/ast.go +++ b/ast.go @@ -701,8 +701,6 @@ retry: case *tyTypeAsParams: return matchFuncCall(pkg, chgObject(pkg, ft.obj, fn), args, flags|instrFlagGopxFunc) } - } else if IsCSignature(t) { - sig = types.NewSignatureType(nil, nil, nil, t.Params(), t.Results(), t.Variadic()) } else { sig = t } @@ -950,11 +948,13 @@ func restoreArgs(args []*internal.Elem, backup []backupElem) { } } +/* func copyArgs(args []*internal.Elem) []*internal.Elem { backup := make([]*internal.Elem, len(args)) copy(backup, args) return backup } +*/ func untypeBig(pkg *Package, cval constant.Value, tyRet types.Type) (*internal.Elem, bool) { switch tyRet { diff --git a/builtin_test.go b/builtin_test.go index c179c9a7..797dbf92 100644 --- a/builtin_test.go +++ b/builtin_test.go @@ -302,25 +302,6 @@ func TestGetSrcPos(t *testing.T) { } } -func TestExportFields(t *testing.T) { - pkg := NewPackage("", "foo", nil) - fields := []*types.Var{ - types.NewField(token.NoPos, pkg.Types, "Y", types.Typ[types.Int], false), - types.NewField(token.NoPos, pkg.Types, "X__u", types.Typ[types.String], false), - } - tyT := pkg.NewType("T").InitType(pkg, types.NewStruct(fields, nil)) - pkg.ExportFields(tyT) - if name := pkg.cb.getFieldName(tyT, "y"); name != "Y" { - t.Fatal("getFieldName y:", name) - } - if name := pkg.cb.getFieldName(tyT, "__u"); name != "X__u" { - t.Fatal("getFieldName __u:", name) - } - if CPubName("123") != "123" { - t.Fatal("CPubName(123) failed") - } -} - func TestIsTypeEx(t *testing.T) { pkg := types.NewPackage("", "foo") o := NewInstruction(0, pkg, "bar", lenInstr{}) @@ -699,13 +680,6 @@ func TestToVariadic(t *testing.T) { func TestToType(t *testing.T) { pkg := NewPackage("", "foo", gblConf) - cf := NewCSignature(nil, nil, false) - if !IsCSignature(cf) { - t.Fatal("IsCSignature failed: not c function?") - } - if v := typString(pkg, cf); v != "func()" { - t.Fatal("toType failed:", v) - } toType(pkg, &unboundType{tBound: tyInt}) defer func() { if e := recover(); e == nil { @@ -715,6 +689,7 @@ func TestToType(t *testing.T) { toType(pkg, &unboundType{}) } +/* func typString(pkg *Package, t types.Type) string { v := toType(pkg, t) var b bytes.Buffer @@ -724,6 +699,7 @@ func typString(pkg *Package, t types.Type) string { } return b.String() } +*/ func TestMethodAutoProperty(t *testing.T) { pkg := types.NewPackage("", "") @@ -786,16 +762,11 @@ func TestHasAutoProperty(t *testing.T) { func TestTypeEx(t *testing.T) { subst := &TySubst{} - bfReft := &bfRefType{typ: tyInt} - if typ, ok := DerefType(bfReft); !ok || typ != tyInt { - t.Fatal("TestDerefType failed") - } pkg := NewPackage("example.com/foo", "foo", gblConf) tyInt := types.Typ[types.Int] typs := []types.Type{ &refType{}, subst, - bfReft, &unboundType{}, &unboundMapElemType{}, &TyOverloadFunc{}, @@ -811,9 +782,6 @@ func TestTypeEx(t *testing.T) { &TemplateParamType{}, &TemplateSignature{}, } - if v := bfReft.String(); v != "bfRefType{typ: int:0 off: 0}" { - t.Fatal("bfRefType.String:", v) - } if v := subst.String(); v != "substType{real: }" { t.Fatal("substType.String:", v) } @@ -1307,37 +1275,6 @@ func TestCallIncDec(t *testing.T) { callIncDec(pkg, args, token.INC) } -func TestVFields(t *testing.T) { - pkg := NewPackage("", "foo", gblConf) - typ := types.NewNamed(types.NewTypeName(token.NoPos, pkg.Types, "bar", nil), tyInt, nil) - _, ok := pkg.VFields(typ) - if ok { - t.Fatal("VFields?") - } - { - flds := NewUnionFields([]*UnionField{ - {Name: "foo"}, - }) - if flds.Len() != 1 { - t.Fatal("UnionFields.len != 1") - } - if flds.At(0).Name != "foo" { - t.Fatal("UnionField.name != foo") - } - } - { - flds := NewBitFields([]*BitField{ - {Name: "foo"}, - }) - if flds.Len() != 1 { - t.Fatal("BitFields.len != 1") - } - if flds.At(0).Name != "foo" { - t.Fatal("BitField.name != foo") - } - } -} - func TestTypeAST(t *testing.T) { pkg := NewPackage("", "foo", gblConf) fset := token.NewFileSet() diff --git a/c.go b/c.go index 5e63ae77..e0d66628 100644 --- a/c.go +++ b/c.go @@ -13,6 +13,12 @@ package gogen +import ( + "go/ast" + "go/types" +) + +/* import ( "go/ast" "go/token" @@ -266,5 +272,26 @@ func IsMethodRecv(recv *types.Var) bool { func isCSigRecv(recv *types.Var) bool { return recv.Type() == types.Typ[types.UntypedNil] } +*/ + +type none = struct{} + +// ---------------------------------------------------------------------------- + +func (p *CodeBuilder) getFieldName(t *types.Named, name string) string { + return name +} + +func (p *CodeBuilder) findVField(t *types.Named, name string, arg *Element, src ast.Node) MemberKind { + return MemberInvalid +} + +func (p *CodeBuilder) refVField(t *types.Named, name string, src ast.Node) MemberKind { + return MemberInvalid +} + +func IsMethodRecv(recv *types.Var) bool { + return recv != nil +} // ---------------------------------------------------------------------------- diff --git a/c_test.go b/c_test.go index 72e85d43..b2075484 100644 --- a/c_test.go +++ b/c_test.go @@ -13,6 +13,7 @@ package gogen_test +/* import ( "go/token" "go/types" @@ -175,5 +176,5 @@ func test() { } `) } - +*/ // ---------------------------------------------------------------------------- diff --git a/codebuild.go b/codebuild.go index 7c3bc9c8..72ff60d6 100644 --- a/codebuild.go +++ b/codebuild.go @@ -143,7 +143,6 @@ type CodeBuilder struct { loadNamed LoadNamedFunc handleErr func(err error) closureParamInsts - vFieldsMgr iotav int commentOnce bool noSkipConst bool @@ -2116,24 +2115,11 @@ func (p *CodeBuilder) doAssignWith(lhs, rhs int, src ast.Node) *CodeBuilder { } } if lhs == rhs { - mkBlockStmt = hasBfRefType(args) - if mkBlockStmt { // { - args = copyArgs(args) - p.stk.PopN(lhs << 1) - p.Block() - } for i := 0; i < lhs; i++ { lhsType := args[i].Type - bfr, bfAssign := lhsType.(*bfRefType) - if bfAssign { - lhsType = &refType{typ: bfr.typ} - } checkAssignType(p.pkg, lhsType, args[lhs+i]) stmt.Lhs[i] = args[i].Val stmt.Rhs[i] = args[lhs+i].Val - if bfAssign { - bfr.assign(p, &stmt.Lhs[i], &stmt.Rhs[i]) - } } } else { pos := getSrcPos(src) @@ -2150,15 +2136,6 @@ done: return p } -func hasBfRefType(args []*internal.Elem) bool { - for _, arg := range args { - if _, ok := arg.Type.(*bfRefType); ok { - return true - } - } - return false -} - func lookupMethod(t *types.Named, name string) types.Object { for i, n := 0, t.NumMethods(); i < n; i++ { m := t.Method(i) diff --git a/cpackages/import.go b/cpackages/import.go deleted file mode 100644 index 45471723..00000000 --- a/cpackages/import.go +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright 2022 The GoPlus Authors (goplus.org) - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package cpackages - -import ( - "go/types" - - "github.com/goplus/gogen" -) - -// ---------------------------------------------------------------------------- - -type PkgRef struct { - pkg gogen.PkgRef - public map[string]string -} - -func (p *PkgRef) Pkg() gogen.PkgRef { - return p.pkg -} - -func (p *PkgRef) Lookup(name string) types.Object { - if goName, ok := p.public[name]; ok { - if goName == "" { - goName = gogen.CPubName(name) - } - return p.pkg.TryRef(goName) - } - return nil -} - -func PubName(name string) string { - return gogen.CPubName(name) -} - -// ---------------------------------------------------------------------------- - -type Config struct { - Pkg *gogen.Package - LookupPub func(pkgPath string) (pubfile string, err error) -} - -type Importer struct { - loaded map[string]PkgRef - lookupPub func(pkgPath string) (pubfile string, err error) - pkg *gogen.Package -} - -func NewImporter(conf *Config) *Importer { - return &Importer{ - loaded: make(map[string]PkgRef), - lookupPub: conf.LookupPub, - pkg: conf.Pkg, - } -} - -func (p *Importer) Import(pkgPath string) (pkg PkgRef, err error) { - if ret, ok := p.loaded[pkgPath]; ok { - return ret, nil - } - pubfile, err := p.lookupPub(pkgPath) - if err != nil { - return - } - public, err := ReadPubFile(pubfile) - if err != nil { - return - } - pkgImp := p.pkg.Import(pkgPath) - pkg = PkgRef{pkg: pkgImp, public: public} - p.loaded[pkgPath] = pkg - return -} - -// ---------------------------------------------------------------------------- diff --git a/cpackages/pubfile.go b/cpackages/pubfile.go deleted file mode 100644 index 79f5f37d..00000000 --- a/cpackages/pubfile.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - Copyright 2022 The GoPlus Authors (goplus.org) - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package cpackages - -import ( - "fmt" - "os" - "sort" - "strings" -) - -// ---------------------------------------------------------------------------- - -func ReadPubFile(pubfile string) (ret map[string]string, err error) { - b, err := os.ReadFile(pubfile) - if err != nil { - if os.IsNotExist(err) { - return make(map[string]string), nil - } - return - } - - text := string(b) - lines := strings.Split(text, "\n") - ret = make(map[string]string, len(lines)) - for i, line := range lines { - flds := strings.Fields(line) - goName := "" - switch len(flds) { - case 1: - case 2: - goName = flds[1] - case 0: - continue - default: - err = fmt.Errorf("%s:%d: too many fields", pubfile, i+1) - return - } - ret[flds[0]] = goName - } - return -} - -// ---------------------------------------------------------------------------- - -func WritePubFile(file string, public map[string]string) (err error) { - if len(public) == 0 { - return - } - f, err := os.Create(file) - if err != nil { - return - } - defer f.Close() - ret := make([]string, 0, len(public)) - for name, goName := range public { - if goName == "" { - ret = append(ret, name) - } else { - ret = append(ret, name+" "+goName) - } - } - sort.Strings(ret) - _, err = f.WriteString(strings.Join(ret, "\n")) - return -} - -// ---------------------------------------------------------------------------- diff --git a/type_ext.go b/type_ext.go index a8048da3..d075ebda 100644 --- a/type_ext.go +++ b/type_ext.go @@ -137,6 +137,7 @@ func (p *TySubst) String() string { return fmt.Sprintf("substType{real: %v}", p.Real) } +// TODO(xsw): check only c2go uses this function. func NewSubst(pos token.Pos, pkg *types.Package, name string, real types.Object) *types.Var { return types.NewVar(pos, pkg, name, &TySubst{Real: real}) } @@ -189,24 +190,10 @@ func DerefType(typ types.Type) (types.Type, bool) { switch t := typ.(type) { case *refType: return t.Elem(), true - case *bfRefType: - return t.typ, true } return typ, false } -// bfRefType: bit field refType -type bfRefType struct { - typ *types.Basic - off int - bits int -} - -func (p *bfRefType) Underlying() types.Type { return p } -func (p *bfRefType) String() string { - return fmt.Sprintf("bfRefType{typ: %v:%d off: %d}", p.typ, p.bits, p.off) -} - // unboundType: unbound type type unboundType struct { tBound types.Type From 3a1f39abf8fc7680914fc298bca44bb60984f020 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Sat, 18 May 2024 19:12:47 +0800 Subject: [PATCH 2/2] remove c.go --- c.go | 297 --------------------------------------------------- c_test.go | 180 ------------------------------- codebuild.go | 13 +-- func.go | 4 + import.go | 2 + 5 files changed, 8 insertions(+), 488 deletions(-) delete mode 100644 c.go delete mode 100644 c_test.go diff --git a/c.go b/c.go deleted file mode 100644 index e0d66628..00000000 --- a/c.go +++ /dev/null @@ -1,297 +0,0 @@ -/* - Copyright 2022 The GoPlus Authors (goplus.org) - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package gogen - -import ( - "go/ast" - "go/types" -) - -/* -import ( - "go/ast" - "go/token" - "go/types" - "strconv" - - "github.com/goplus/gogen/internal" -) - -// ---------------------------------------------------------------------------- - -type VFields interface { // virtual fields - FindField(cb *CodeBuilder, t *types.Named, name string, arg *Element, src ast.Node) MemberKind - FieldRef(cb *CodeBuilder, t *types.Named, name string, src ast.Node) MemberKind -} - -type none = struct{} - -type vFieldsMgr struct { - vfts map[*types.Named]VFields - pubs map[*types.Named]none -} - -func CPubName(name string) string { - if r := name[0]; 'a' <= r && r <= 'z' { - r -= 'a' - 'A' - return string(r) + name[1:] - } else if r == '_' { - return "X" + name - } - return name -} - -func (p *CodeBuilder) getFieldName(t *types.Named, name string) string { - if _, ok := p.pubs[t]; ok { - return CPubName(name) - } - return name -} - -func (p *CodeBuilder) refVField(t *types.Named, name string, src ast.Node) MemberKind { - if vft, ok := p.vfts[t]; ok { - return vft.FieldRef(p, t, name, src) - } - return MemberInvalid -} - -func (p *CodeBuilder) findVField(t *types.Named, name string, arg *Element, src ast.Node) MemberKind { - if vft, ok := p.vfts[t]; ok { - return vft.FindField(p, t, name, arg, src) - } - return MemberInvalid -} - -func (p *Package) ExportFields(t *types.Named) { - if p.cb.pubs == nil { - p.cb.pubs = make(map[*types.Named]none) - } - p.cb.pubs[t] = none{} -} - -func (p *Package) SetVFields(t *types.Named, vft VFields) { - if p.cb.vfts == nil { - p.cb.vfts = make(map[*types.Named]VFields) - } - p.cb.vfts[t] = vft -} - -func (p *Package) VFields(t *types.Named) (vft VFields, ok bool) { - vft, ok = p.cb.vfts[t] - return -} - -// ---------------------------------------------------------------------------- - -type BitField struct { - Name string // bit field name - FldName string // real field name - Off int - Bits int - Pos token.Pos -} - -type BitFields struct { - flds []*BitField -} - -func NewBitFields(flds []*BitField) *BitFields { - return &BitFields{flds: flds} -} - -func (p *BitFields) At(i int) *BitField { - return p.flds[i] -} - -func (p *BitFields) Len() int { - return len(p.flds) -} - -func (p *BitFields) FindField( - cb *CodeBuilder, t *types.Named, name string, arg *Element, src ast.Node) MemberKind { - for _, v := range p.flds { - if v.Name == name { - o := t.Underlying().(*types.Struct) - if kind := cb.field(o, v.FldName, "", MemberFlagVal, arg, src); kind != MemberInvalid { - tfld := cb.stk.Get(-1).Type.(*types.Basic) - if (tfld.Info() & types.IsUnsigned) != 0 { - if v.Off != 0 { - cb.Val(v.Off).BinaryOp(token.SHR) - } - cb.Val((1 << v.Bits) - 1).BinaryOp(token.AND) - } else { - bits := int(std.Sizeof(tfld)<<3) - v.Bits - cb.Val(bits - v.Off).BinaryOp(token.SHL).Val(bits).BinaryOp(token.SHR) - } - return kind - } - } - } - return MemberInvalid -} - -func (p *bfRefType) assign(cb *CodeBuilder, lhs, rhs *ast.Expr) { - // *addr = *addr &^ ((1 << bits) - 1) << off) | ((rhs & (1 << bits) - 1)) << off) - tname := cb.pkg.autoName() - tvar := ident(tname) - addr := &ast.UnaryExpr{Op: token.AND, X: *lhs} - stmt := &ast.AssignStmt{Lhs: []ast.Expr{tvar}, Tok: token.DEFINE, Rhs: []ast.Expr{addr}} - cb.emitStmt(stmt) - mask0 := (1 << p.bits) - 1 - mask := mask0 << p.off - maskLit0 := &ast.BasicLit{Kind: token.INT, Value: strconv.Itoa(mask0)} - maskLit := &ast.BasicLit{Kind: token.INT, Value: strconv.Itoa(mask)} - valMask := &ast.BinaryExpr{X: &ast.StarExpr{X: tvar}, Op: token.AND_NOT, Y: maskLit} - rhsExpr := &ast.BinaryExpr{X: *rhs, Op: token.AND, Y: maskLit0} - if p.off != 0 { - offLit := &ast.BasicLit{Kind: token.INT, Value: strconv.Itoa(p.off)} - rhsExpr = &ast.BinaryExpr{X: rhsExpr, Op: token.SHL, Y: offLit} - } - *lhs = &ast.StarExpr{X: tvar} - *rhs = &ast.BinaryExpr{X: valMask, Op: token.OR, Y: rhsExpr} -} - -func (p *BitFields) FieldRef(cb *CodeBuilder, t *types.Named, name string, src ast.Node) MemberKind { - for _, v := range p.flds { - if v.Name == name { - stk := cb.stk - o := t.Underlying().(*types.Struct) - if cb.fieldRef(stk.Get(-1).Val, o, v.FldName, src) { - fld := stk.Get(-1) - tfld := fld.Type.(*refType).typ.(*types.Basic) - stk.Ret(1, &internal.Elem{ - Val: fld.Val, Src: src, - Type: &bfRefType{typ: tfld, bits: v.Bits, off: v.Off}, - }) - return MemberField - } - } - } - return MemberInvalid -} - -// ---------------------------------------------------------------------------- - -type UnionField struct { - Name string - Off int - Type types.Type - Pos token.Pos -} - -type UnionFields struct { - flds []*UnionField -} - -func NewUnionFields(flds []*UnionField) *UnionFields { - return &UnionFields{flds: flds} -} - -func (p *UnionFields) At(i int) *UnionField { - return p.flds[i] -} - -func (p *UnionFields) Len() int { - return len(p.flds) -} - -func (p *UnionFields) getField( - cb *CodeBuilder, tfld *types.Named, name string, _ ast.Node, ref bool) MemberKind { - for _, v := range p.flds { - if v.Name == name { - obj := cb.stk.Pop() - tobj, isPtr := obj.Type, false - if tt, ok := tobj.(*types.Pointer); ok { - tobj, isPtr = tt.Elem(), true - } - cb.Typ(types.NewPointer(v.Type)).Typ(types.Typ[types.UnsafePointer]) - if v.Off != 0 { - cb.Typ(types.Typ[types.Uintptr]).Typ(types.Typ[types.UnsafePointer]) - } - cb.stk.Push(obj) - if tt, ok := tobj.(*types.Named); ok && tt == tfld { // it's an union type - if !isPtr { - cb.UnaryOp(token.AND) - } - } else { // it's a type contains a field with union type - cb.MemberRef(tfld.Obj().Name()).UnaryOp(token.AND) - } - if v.Off != 0 { - cb.Call(1).Call(1).Val(v.Off).BinaryOp(token.ADD) // => voidptr => uintptr - } - cb.Call(1).Call(1) // => voidptr => *type - if ref { - cb.ElemRef() - } else { - cb.Elem() - } - return MemberField - } - } - return MemberInvalid -} - -func (p *UnionFields) FindField( - cb *CodeBuilder, tfld *types.Named, name string, arg *Element, src ast.Node) MemberKind { - return p.getField(cb, tfld, name, src, false) -} - -func (p *UnionFields) FieldRef(cb *CodeBuilder, tfld *types.Named, name string, src ast.Node) MemberKind { - return p.getField(cb, tfld, name, src, true) -} - -// ---------------------------------------------------------------------------- - -// NewCSignature creates prototype of a C function. -func NewCSignature(params, results *types.Tuple, variadic bool) *types.Signature { - crecv := types.NewParam(token.NoPos, nil, "", types.Typ[types.UntypedNil]) - return types.NewSignatureType(crecv, nil, nil, params, results, variadic) -} - -// IsCSignature checks a prototype is C function or not. -func IsCSignature(sig *types.Signature) bool { - recv := sig.Recv() - return recv != nil && isCSigRecv(recv) -} - -func IsMethodRecv(recv *types.Var) bool { - return recv != nil && !isCSigRecv(recv) -} - -func isCSigRecv(recv *types.Var) bool { - return recv.Type() == types.Typ[types.UntypedNil] -} -*/ - -type none = struct{} - -// ---------------------------------------------------------------------------- - -func (p *CodeBuilder) getFieldName(t *types.Named, name string) string { - return name -} - -func (p *CodeBuilder) findVField(t *types.Named, name string, arg *Element, src ast.Node) MemberKind { - return MemberInvalid -} - -func (p *CodeBuilder) refVField(t *types.Named, name string, src ast.Node) MemberKind { - return MemberInvalid -} - -func IsMethodRecv(recv *types.Var) bool { - return recv != nil -} - -// ---------------------------------------------------------------------------- diff --git a/c_test.go b/c_test.go deleted file mode 100644 index b2075484..00000000 --- a/c_test.go +++ /dev/null @@ -1,180 +0,0 @@ -/* - Copyright 2022 The GoPlus Authors (goplus.org) - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package gogen_test - -/* -import ( - "go/token" - "go/types" - "testing" - - "github.com/goplus/gogen" -) - -// ---------------------------------------------------------------------------- - -func TestBitFields(t *testing.T) { - pkg := newMainPackage() - fields := []*types.Var{ - types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), - types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.Uint], false), - } - tyT := pkg.NewType("T").InitType(pkg, types.NewStruct(fields, nil)) - pkg.SetVFields(tyT, gogen.NewBitFields([]*gogen.BitField{ - {Name: "z1", FldName: "x", Off: 0, Bits: 1}, - {Name: "z2", FldName: "x", Off: 1, Bits: 3}, - {Name: "u1", FldName: "y", Off: 0, Bits: 1}, - {Name: "u2", FldName: "y", Off: 1, Bits: 3}, - })) - cb := pkg.NewFunc(nil, "test", nil, nil, false).BodyStart(pkg). - NewVar(tyT, "a"). - NewVarStart(types.Typ[types.Int], "z"). - VarVal("a").MemberVal("z1").UnaryOp(token.SUB). - VarVal("a").MemberVal("z2"). - BinaryOp(token.MUL).EndInit(1). - NewVarStart(types.Typ[types.Uint], "u"). - VarVal("a").MemberVal("u1").UnaryOp(token.XOR). - VarVal("a").MemberVal("u2"). - BinaryOp(token.MUL).EndInit(1). - VarVal("a").MemberRef("z1").Val(1).Assign(1). - VarVal("a").MemberRef("z2").Val(1).Assign(1). - End() - domTest(t, pkg, `package main - -type T struct { - x int - y uint -} - -func test() { - var a T - var z int = -(a.x << 63 >> 63) * (a.x << 60 >> 61) - var u uint = ^(a.y & 1) * (a.y >> 1 & 7) - { - _autoGo_1 := &a.x - *_autoGo_1 = *_autoGo_1&^1 | 1&1 - } - { - _autoGo_2 := &a.x - *_autoGo_2 = *_autoGo_2&^14 | 1&7<<1 - } -} -`) - cb.NewVar(tyT, "a").VarVal("a") - func() { - defer func() { - if e := recover(); e == nil { - t.Fatal("TestBitFields: no error?") - } - }() - cb.MemberVal("z3") - }() - func() { - defer func() { - if e := recover(); e == nil { - t.Fatal("TestBitFields: no error?") - } - }() - cb.MemberRef("z3") - }() -} - -func TestUnionFields(t *testing.T) { - pkg := newMainPackage() - fields := []*types.Var{ - types.NewField(token.NoPos, pkg.Types, "x", types.Typ[types.Int], false), - types.NewField(token.NoPos, pkg.Types, "y", types.Typ[types.String], false), - } - tyT := pkg.NewType("T").InitType(pkg, types.NewStruct(fields, nil)) - tyFlt := types.Typ[types.Float32] - pkg.SetVFields(tyT, gogen.NewUnionFields([]*gogen.UnionField{ - {Name: "z", Type: tyFlt}, - {Name: "val", Type: tyFlt, Off: 4}, - })) - barFields := []*types.Var{ - types.NewField(token.NoPos, pkg.Types, "a", types.Typ[types.Int], false), - types.NewField(token.NoPos, pkg.Types, "T", tyT, true), - } - tyBar := pkg.NewType("Bar").InitType(pkg, types.NewStruct(barFields, nil)) - cb := pkg.NewFunc(nil, "test", nil, nil, false).BodyStart(pkg). - NewVar(tyT, "a").NewVar(types.NewPointer(tyT), "b"). - NewVar(tyBar, "bara").NewVar(types.NewPointer(tyBar), "barb"). - NewVarStart(tyFlt, "z").VarVal("a").MemberVal("z").EndInit(1). - NewVarStart(tyFlt, "val").VarVal("a").MemberVal("val").EndInit(1). - NewVarStart(tyFlt, "z2").VarVal("b").MemberVal("z").EndInit(1). - NewVarStart(tyFlt, "val2").VarVal("b").MemberVal("val").EndInit(1). - NewVarStart(tyFlt, "barz").Val(ctxRef(pkg, "bara")).MemberVal("z").EndInit(1). - NewVarStart(tyFlt, "barval").Val(ctxRef(pkg, "bara")).MemberVal("val").EndInit(1). - NewVarStart(tyFlt, "barz2").Val(ctxRef(pkg, "barb")).MemberVal("z").EndInit(1). - NewVarStart(tyFlt, "barval2").Val(ctxRef(pkg, "barb")).MemberVal("val").EndInit(1). - VarVal("a").MemberRef("z").Val(1).Assign(1). - Val(ctxRef(pkg, "barb")).MemberRef("val").Val(1.2).Assign(1). - End() - domTest(t, pkg, `package main - -import "unsafe" - -type T struct { - x int - y string -} -type Bar struct { - a int - T -} - -func test() { - var a T - var b *T - var bara Bar - var barb *Bar - var z float32 = *(*float32)(unsafe.Pointer(&a)) - var val float32 = *(*float32)(unsafe.Pointer(uintptr(unsafe.Pointer(&a)) + 4)) - var z2 float32 = *(*float32)(unsafe.Pointer(b)) - var val2 float32 = *(*float32)(unsafe.Pointer(uintptr(unsafe.Pointer(b)) + 4)) - var barz float32 = *(*float32)(unsafe.Pointer(&bara.T)) - var barval float32 = *(*float32)(unsafe.Pointer(uintptr(unsafe.Pointer(&bara.T)) + 4)) - var barz2 float32 = *(*float32)(unsafe.Pointer(&barb.T)) - var barval2 float32 = *(*float32)(unsafe.Pointer(uintptr(unsafe.Pointer(&barb.T)) + 4)) - *(*float32)(unsafe.Pointer(&a)) = 1 - *(*float32)(unsafe.Pointer(uintptr(unsafe.Pointer(&barb.T)) + 4)) = 1.2 -} -`) - defer func() { - if e := recover(); e == nil { - t.Fatal("TestUnionFields: no error?") - } - }() - cb.NewVar(tyT, "a").VarVal("a").MemberVal("unknown") -} - -// ---------------------------------------------------------------------------- - -func TestCFunc(t *testing.T) { - pkg := newMainPackage() - cfn := gogen.NewCSignature(nil, nil, false) - pkg.NewFunc(nil, "test", nil, nil, false).BodyStart(pkg). - NewVar(cfn, "f"). - VarVal("f").Call(0).EndStmt(). - End() - domTest(t, pkg, `package main - -func test() { - var f func() - f() -} -`) -} -*/ -// ---------------------------------------------------------------------------- diff --git a/codebuild.go b/codebuild.go index 72ff60d6..79cbe94f 100644 --- a/codebuild.go +++ b/codebuild.go @@ -1461,11 +1461,9 @@ func (p *CodeBuilder) refMember(typ types.Type, name string, argVal ast.Expr, sr switch o := indirect(typ).(type) { case *types.Named: if struc, ok := p.getUnderlying(o).(*types.Struct); ok { - name = p.getFieldName(o, name) if p.fieldRef(argVal, struc, name, src) { return MemberField } - return p.refVField(o, name, argVal) } case *types.Struct: if p.fieldRef(argVal, o, name, src) { @@ -1495,7 +1493,7 @@ func (p *CodeBuilder) fieldRef(x ast.Expr, o *types.Struct, name string, src ast if t, ok := fldt.(*types.Named); ok { u := p.getUnderlying(t) if struc, ok := u.(*types.Struct); ok { - if p.fieldRef(x, struc, name, src) || p.refVField(t, name, nil) != MemberInvalid { + if p.fieldRef(x, struc, name, src) { return true } } @@ -1625,7 +1623,6 @@ retry: u := p.getUnderlying(t) // may cause to loadNamed (delay-loaded) struc, fstruc := u.(*types.Struct) if fstruc { - name = p.getFieldName(t, name) if kind := p.normalField(struc, name, arg, srcExpr); kind != MemberInvalid { return kind } @@ -1634,9 +1631,6 @@ retry: return kind } if fstruc { - if kind := p.findVField(t, name, arg, srcExpr); kind != MemberInvalid { - return kind - } return p.embeddedField(struc, name, aliasName, flag, arg, srcExpr) } case *types.Struct: @@ -1649,16 +1643,13 @@ retry: if kind := p.method(o, name, aliasName, flag, arg, srcExpr); kind != MemberInvalid { return kind } - if _, ok := typ.(*types.Struct); ok { - name = p.getFieldName(o, name) - } goto retry case *types.Struct: if kind := p.field(o, name, aliasName, flag, arg, srcExpr); kind != MemberInvalid { return kind } if named != nil { - return p.findVField(named, name, arg, srcExpr) + return MemberInvalid } case *types.Interface: o.Complete() diff --git a/func.go b/func.go index 1473b103..22c92c3c 100644 --- a/func.go +++ b/func.go @@ -160,6 +160,10 @@ func getRecv(recvTypePos func() token.Pos) token.Pos { return token.NoPos } +func IsMethodRecv(recv *types.Var) bool { + return recv != nil +} + // NewFuncWith creates a new function (should have a function body). func (p *Package) NewFuncWith( pos token.Pos, name string, sig *types.Signature, recvTypePos func() token.Pos) (*Func, error) { diff --git a/import.go b/import.go index 5959144b..f18d63c4 100644 --- a/import.go +++ b/import.go @@ -378,6 +378,8 @@ const ( // ---------------------------------------------------------------------------- +type none = struct{} + type expDeps struct { this *types.Package ret map[*types.Package]none