1// Copyright 2013 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package ir 6 7// lvalues are the union of addressable expressions and map-index 8// expressions. 9 10import ( 11 "go/ast" 12 "go/types" 13) 14 15// An lvalue represents an assignable location that may appear on the 16// left-hand side of an assignment. This is a generalization of a 17// pointer to permit updates to elements of maps. 18// 19type lvalue interface { 20 store(fn *Function, v Value, source ast.Node) // stores v into the location 21 load(fn *Function, source ast.Node) Value // loads the contents of the location 22 address(fn *Function) Value // address of the location 23 typ() types.Type // returns the type of the location 24} 25 26// An address is an lvalue represented by a true pointer. 27type address struct { 28 addr Value 29 expr ast.Expr // source syntax of the value (not address) [debug mode] 30} 31 32func (a *address) load(fn *Function, source ast.Node) Value { 33 return emitLoad(fn, a.addr, source) 34} 35 36func (a *address) store(fn *Function, v Value, source ast.Node) { 37 store := emitStore(fn, a.addr, v, source) 38 if a.expr != nil { 39 // store.Val is v, converted for assignability. 40 emitDebugRef(fn, a.expr, store.Val, false) 41 } 42} 43 44func (a *address) address(fn *Function) Value { 45 if a.expr != nil { 46 emitDebugRef(fn, a.expr, a.addr, true) 47 } 48 return a.addr 49} 50 51func (a *address) typ() types.Type { 52 return deref(a.addr.Type()) 53} 54 55// An element is an lvalue represented by m[k], the location of an 56// element of a map. These locations are not addressable 57// since pointers cannot be formed from them, but they do support 58// load() and store(). 59// 60type element struct { 61 m, k Value // map 62 t types.Type // map element type 63} 64 65func (e *element) load(fn *Function, source ast.Node) Value { 66 l := &MapLookup{ 67 X: e.m, 68 Index: e.k, 69 } 70 l.setType(e.t) 71 return fn.emit(l, source) 72} 73 74func (e *element) store(fn *Function, v Value, source ast.Node) { 75 up := &MapUpdate{ 76 Map: e.m, 77 Key: e.k, 78 Value: emitConv(fn, v, e.t, source), 79 } 80 fn.emit(up, source) 81} 82 83func (e *element) address(fn *Function) Value { 84 panic("map elements are not addressable") 85} 86 87func (e *element) typ() types.Type { 88 return e.t 89} 90 91// A blank is a dummy variable whose name is "_". 92// It is not reified: loads are illegal and stores are ignored. 93// 94type blank struct{} 95 96func (bl blank) load(fn *Function, source ast.Node) Value { 97 panic("blank.load is illegal") 98} 99 100func (bl blank) store(fn *Function, v Value, source ast.Node) { 101 s := &BlankStore{ 102 Val: v, 103 } 104 fn.emit(s, source) 105} 106 107func (bl blank) address(fn *Function) Value { 108 panic("blank var is not addressable") 109} 110 111func (bl blank) typ() types.Type { 112 // This should be the type of the blank Ident; the typechecker 113 // doesn't provide this yet, but fortunately, we don't need it 114 // yet either. 115 panic("blank.typ is unimplemented") 116} 117