Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools@v0.0.0-20201105173854-bc9fc8d8c4bc / go / ssa / lvalue.go
diff --git a/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/ssa/lvalue.go b/.config/coc/extensions/coc-go-data/tools/pkg/mod/golang.org/x/tools@v0.0.0-20201105173854-bc9fc8d8c4bc/go/ssa/lvalue.go
new file mode 100644 (file)
index 0000000..4d85be3
--- /dev/null
@@ -0,0 +1,120 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ssa
+
+// lvalues are the union of addressable expressions and map-index
+// expressions.
+
+import (
+       "go/ast"
+       "go/token"
+       "go/types"
+)
+
+// An lvalue represents an assignable location that may appear on the
+// left-hand side of an assignment.  This is a generalization of a
+// pointer to permit updates to elements of maps.
+//
+type lvalue interface {
+       store(fn *Function, v Value) // stores v into the location
+       load(fn *Function) Value     // loads the contents of the location
+       address(fn *Function) Value  // address of the location
+       typ() types.Type             // returns the type of the location
+}
+
+// An address is an lvalue represented by a true pointer.
+type address struct {
+       addr Value
+       pos  token.Pos // source position
+       expr ast.Expr  // source syntax of the value (not address) [debug mode]
+}
+
+func (a *address) load(fn *Function) Value {
+       load := emitLoad(fn, a.addr)
+       load.pos = a.pos
+       return load
+}
+
+func (a *address) store(fn *Function, v Value) {
+       store := emitStore(fn, a.addr, v, a.pos)
+       if a.expr != nil {
+               // store.Val is v, converted for assignability.
+               emitDebugRef(fn, a.expr, store.Val, false)
+       }
+}
+
+func (a *address) address(fn *Function) Value {
+       if a.expr != nil {
+               emitDebugRef(fn, a.expr, a.addr, true)
+       }
+       return a.addr
+}
+
+func (a *address) typ() types.Type {
+       return deref(a.addr.Type())
+}
+
+// An element is an lvalue represented by m[k], the location of an
+// element of a map or string.  These locations are not addressable
+// since pointers cannot be formed from them, but they do support
+// load(), and in the case of maps, store().
+//
+type element struct {
+       m, k Value      // map or string
+       t    types.Type // map element type or string byte type
+       pos  token.Pos  // source position of colon ({k:v}) or lbrack (m[k]=v)
+}
+
+func (e *element) load(fn *Function) Value {
+       l := &Lookup{
+               X:     e.m,
+               Index: e.k,
+       }
+       l.setPos(e.pos)
+       l.setType(e.t)
+       return fn.emit(l)
+}
+
+func (e *element) store(fn *Function, v Value) {
+       up := &MapUpdate{
+               Map:   e.m,
+               Key:   e.k,
+               Value: emitConv(fn, v, e.t),
+       }
+       up.pos = e.pos
+       fn.emit(up)
+}
+
+func (e *element) address(fn *Function) Value {
+       panic("map/string elements are not addressable")
+}
+
+func (e *element) typ() types.Type {
+       return e.t
+}
+
+// A blank is a dummy variable whose name is "_".
+// It is not reified: loads are illegal and stores are ignored.
+//
+type blank struct{}
+
+func (bl blank) load(fn *Function) Value {
+       panic("blank.load is illegal")
+}
+
+func (bl blank) store(fn *Function, v Value) {
+       // no-op
+}
+
+func (bl blank) address(fn *Function) Value {
+       panic("blank var is not addressable")
+}
+
+func (bl blank) typ() types.Type {
+       // This should be the type of the blank Ident; the typechecker
+       // doesn't provide this yet, but fortunately, we don't need it
+       // yet either.
+       panic("blank.typ is unimplemented")
+}