func buildStarExpr(b *builder, expr *ast.StarExpr) tast.Expr { opPos := expr.Star.Pos addr := b.buildExpr(expr.Expr) if addr == nil { return nil } addrRef := addr.R() if !addrRef.IsSingle() { b.Errorf(opPos, "* on %s", addrRef) return nil } if t, ok := addrRef.T.(*types.Type); ok { return tast.NewType(&types.Pointer{t.T}) } t, ok := addrRef.T.(*types.Pointer) if !ok { b.Errorf(opPos, "* on non-pointer") return nil } r := tast.NewAddressableRef(t.T) return &tast.StarExpr{addr, r} }
func buildExpr(b *builder, expr ast.Expr) tast.Expr { if expr == nil { panic("bug") } switch expr := expr.(type) { case *ast.Operand: return buildOperand(b, expr) case *ast.ParenExpr: return buildExpr(b, expr.Expr) case *ast.MemberExpr: return buildMember(b, expr) case *ast.OpExpr: return buildOpExpr(b, expr) case *ast.StarExpr: return buildStarExpr(b, expr) case *ast.IndexExpr: return buildIndexExpr(b, expr) case *ast.CallExpr: return buildCallExpr(b, expr) case *ast.ArrayTypeExpr: t := b.buildType(expr) if t == nil { return nil } return tast.NewType(t) case *ast.FuncTypeExpr: t := b.buildType(expr) if t == nil { return nil } return tast.NewType(t) case *ast.ExprList: return buildExprList(b, expr) case *ast.ArrayLiteral: return buildArrayLit(b, expr) } b.Errorf(ast.ExprPos(expr), "invalid or not implemented: %T", expr) return nil }