diff --git a/ssa/expr.go b/ssa/expr.go index 9b69c4af..2c5c7770 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -425,7 +425,7 @@ func (b Builder) UnOp(op token.Token, x Expr) (ret Expr) { case token.MUL: return b.Load(x) case token.SUB: - switch t := x.Type.raw.Underlying().(type) { + switch t := x.raw.Type.Underlying().(type) { case *types.Basic: ret.Type = x.Type if t.Info()&types.IsInteger != 0 { diff --git a/ssa/interface.go b/ssa/interface.go index 5aebb33e..7b9c49dc 100644 --- a/ssa/interface.go +++ b/ssa/interface.go @@ -41,7 +41,7 @@ func (b Builder) abiStruct(t *types.Struct) Expr { g := pkg.VarOf(name) if g == nil { prog := b.Prog - g := pkg.doNewVar(name, prog.AbiTypePtrPtr()) + g = pkg.doNewVar(name, prog.AbiTypePtrPtr()) g.Init(prog.Null(g.Type)) } pkg.abitys = append(pkg.abitys, func() { @@ -293,16 +293,13 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr { tabi := b.abiType(assertedTyp.raw.Type) eq := b.BinOp(token.EQL, tx, tabi) if commaOk { - /* - prog := b.Prog - t := prog.Tuple(assertedTyp, prog.Bool()) - val := b.valFromData(assertedTyp, b.InterfaceData(x)) - zero := prog.Zero(assertedTyp) - valTrue := aggregateValue(b.impl, t.ll, val.impl, prog.BoolVal(true).impl) - valFalse := aggregateValue(b.impl, t.ll, zero.impl, prog.BoolVal(false).impl) - return Expr{llvm.CreateSelect(b.impl, eq.impl, valTrue, valFalse), t} - */ - panic("todo") + prog := b.Prog + t := prog.Tuple(assertedTyp, prog.Bool()) + val := b.valFromData(assertedTyp, b.InterfaceData(x)) + zero := prog.Zero(assertedTyp) + valTrue := aggregateValue(b.impl, t.ll, val.impl, prog.BoolVal(true).impl) + valFalse := aggregateValue(b.impl, t.ll, zero.impl, prog.BoolVal(false).impl) + return Expr{llvm.CreateSelect(b.impl, eq.impl, valTrue, valFalse), t} } blks := b.Func.MakeBlocks(2) b.If(eq, blks[0], blks[1]) diff --git a/ssa/package.go b/ssa/package.go index f7a967e9..e7a47720 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -291,13 +291,13 @@ func (p Program) NewPackage(name, pkgPath string) Package { ret := &aPackage{ mod: mod, vars: gbls, fns: fns, stubs: stubs, pyobjs: pyobjs, pymods: pymods, Prog: p} + ret.abi.Init(pkgPath) return ret } // Tuple returns a tuple type. func (p Program) Tuple(typs ...Type) Type { - n := len(typs) - els := make([]*types.Var, n) + els := make([]*types.Var, len(typs)) for i, t := range typs { els[i] = types.NewParam(token.NoPos, nil, "", t.raw.Type) } diff --git a/ssa/type.go b/ssa/type.go index 64314d6c..d8ba01a7 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -75,7 +75,7 @@ func indexType(t types.Type) types.Type { // ----------------------------------------------------------------------------- type rawType struct { - types.Type + Type types.Type } type aType struct { @@ -285,12 +285,14 @@ func (p Program) toType(raw types.Type) Type { return p.toNamed(t) case *types.Signature: // represents a C function pointer in raw type return &aType{p.toLLVMFuncPtr(t), typ, vkFuncPtr} + case *types.Tuple: + return &aType{p.toLLVMTuple(t), typ, vkTuple} case *types.Array: elem := p.rawType(t.Elem()) return &aType{llvm.ArrayType(elem.ll, int(t.Len())), typ, vkArray} case *types.Chan: } - panic(fmt.Sprintf("toLLVMType: todo - %T\n", typ)) + panic(fmt.Sprintf("toLLVMType: todo - %T\n", raw)) } func (p Program) toLLVMNamedStruct(name string, raw *types.Struct) llvm.Type {