You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.9 KiB

  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. package ssa
  5. // lvalues are the union of addressable expressions and map-index
  6. // expressions.
  7. import (
  8. "go/ast"
  9. "go/token"
  10. "go/types"
  11. )
  12. // An lvalue represents an assignable location that may appear on the
  13. // left-hand side of an assignment. This is a generalization of a
  14. // pointer to permit updates to elements of maps.
  15. //
  16. type lvalue interface {
  17. store(fn *Function, v Value) // stores v into the location
  18. load(fn *Function) Value // loads the contents of the location
  19. address(fn *Function) Value // address of the location
  20. typ() types.Type // returns the type of the location
  21. }
  22. // An address is an lvalue represented by a true pointer.
  23. type address struct {
  24. addr Value
  25. pos token.Pos // source position
  26. expr ast.Expr // source syntax of the value (not address) [debug mode]
  27. }
  28. func (a *address) load(fn *Function) Value {
  29. load := emitLoad(fn, a.addr)
  30. load.pos = a.pos
  31. return load
  32. }
  33. func (a *address) store(fn *Function, v Value) {
  34. store := emitStore(fn, a.addr, v, a.pos)
  35. if a.expr != nil {
  36. // store.Val is v, converted for assignability.
  37. emitDebugRef(fn, a.expr, store.Val, false)
  38. }
  39. }
  40. func (a *address) address(fn *Function) Value {
  41. if a.expr != nil {
  42. emitDebugRef(fn, a.expr, a.addr, true)
  43. }
  44. return a.addr
  45. }
  46. func (a *address) typ() types.Type {
  47. return deref(a.addr.Type())
  48. }
  49. // An element is an lvalue represented by m[k], the location of an
  50. // element of a map or string. These locations are not addressable
  51. // since pointers cannot be formed from them, but they do support
  52. // load(), and in the case of maps, store().
  53. //
  54. type element struct {
  55. m, k Value // map or string
  56. t types.Type // map element type or string byte type
  57. pos token.Pos // source position of colon ({k:v}) or lbrack (m[k]=v)
  58. }
  59. func (e *element) load(fn *Function) Value {
  60. l := &Lookup{
  61. X: e.m,
  62. Index: e.k,
  63. }
  64. l.setPos(e.pos)
  65. l.setType(e.t)
  66. return fn.emit(l)
  67. }
  68. func (e *element) store(fn *Function, v Value) {
  69. up := &MapUpdate{
  70. Map: e.m,
  71. Key: e.k,
  72. Value: emitConv(fn, v, e.t),
  73. }
  74. up.pos = e.pos
  75. fn.emit(up)
  76. }
  77. func (e *element) address(fn *Function) Value {
  78. panic("map/string elements are not addressable")
  79. }
  80. func (e *element) typ() types.Type {
  81. return e.t
  82. }
  83. // A blank is a dummy variable whose name is "_".
  84. // It is not reified: loads are illegal and stores are ignored.
  85. //
  86. type blank struct{}
  87. func (bl blank) load(fn *Function) Value {
  88. panic("blank.load is illegal")
  89. }
  90. func (bl blank) store(fn *Function, v Value) {
  91. // no-op
  92. }
  93. func (bl blank) address(fn *Function) Value {
  94. panic("blank var is not addressable")
  95. }
  96. func (bl blank) typ() types.Type {
  97. // This should be the type of the blank Ident; the typechecker
  98. // doesn't provide this yet, but fortunately, we don't need it
  99. // yet either.
  100. panic("blank.typ is unimplemented")
  101. }