github.com/graybobo/golang.org-package-offline-cache@v0.0.0-20200626051047-6608995c132f/x/tools/go/pointer/constraint14.go (about) 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 5 // +build !go1.5 6 7 package pointer 8 9 import ( 10 "golang.org/x/tools/go/types" 11 ) 12 13 type constraint interface { 14 // For a complex constraint, returns the nodeid of the pointer 15 // to which it is attached. For addr and copy, returns dst. 16 ptr() nodeid 17 18 // renumber replaces each nodeid n in the constraint by mapping[n]. 19 renumber(mapping []nodeid) 20 21 // presolve is a hook for constraint-specific behaviour during 22 // pre-solver optimization. Typical implementations mark as 23 // indirect the set of nodes to which the solver will add copy 24 // edges or PTS labels. 25 presolve(h *hvn) 26 27 // solve is called for complex constraints when the pts for 28 // the node to which they are attached has changed. 29 solve(a *analysis, delta *nodeset) 30 31 String() string 32 } 33 34 // dst = &src 35 // pts(dst) ⊇ {src} 36 // A base constraint used to initialize the solver's pt sets 37 type addrConstraint struct { 38 dst nodeid // (ptr) 39 src nodeid 40 } 41 42 func (c *addrConstraint) ptr() nodeid { return c.dst } 43 func (c *addrConstraint) renumber(mapping []nodeid) { 44 c.dst = mapping[c.dst] 45 c.src = mapping[c.src] 46 } 47 48 // dst = src 49 // A simple constraint represented directly as a copyTo graph edge. 50 type copyConstraint struct { 51 dst nodeid // (ptr) 52 src nodeid 53 } 54 55 func (c *copyConstraint) ptr() nodeid { return c.dst } 56 func (c *copyConstraint) renumber(mapping []nodeid) { 57 c.dst = mapping[c.dst] 58 c.src = mapping[c.src] 59 } 60 61 // dst = src[offset] 62 // A complex constraint attached to src (the pointer) 63 type loadConstraint struct { 64 offset uint32 65 dst nodeid 66 src nodeid // (ptr) 67 } 68 69 func (c *loadConstraint) ptr() nodeid { return c.src } 70 func (c *loadConstraint) renumber(mapping []nodeid) { 71 c.dst = mapping[c.dst] 72 c.src = mapping[c.src] 73 } 74 75 // dst[offset] = src 76 // A complex constraint attached to dst (the pointer) 77 type storeConstraint struct { 78 offset uint32 79 dst nodeid // (ptr) 80 src nodeid 81 } 82 83 func (c *storeConstraint) ptr() nodeid { return c.dst } 84 func (c *storeConstraint) renumber(mapping []nodeid) { 85 c.dst = mapping[c.dst] 86 c.src = mapping[c.src] 87 } 88 89 // dst = &src.f or dst = &src[0] 90 // A complex constraint attached to dst (the pointer) 91 type offsetAddrConstraint struct { 92 offset uint32 93 dst nodeid 94 src nodeid // (ptr) 95 } 96 97 func (c *offsetAddrConstraint) ptr() nodeid { return c.src } 98 func (c *offsetAddrConstraint) renumber(mapping []nodeid) { 99 c.dst = mapping[c.dst] 100 c.src = mapping[c.src] 101 } 102 103 // dst = src.(typ) where typ is an interface 104 // A complex constraint attached to src (the interface). 105 // No representation change: pts(dst) and pts(src) contains tagged objects. 106 type typeFilterConstraint struct { 107 typ types.Type // an interface type 108 dst nodeid 109 src nodeid // (ptr) 110 } 111 112 func (c *typeFilterConstraint) ptr() nodeid { return c.src } 113 func (c *typeFilterConstraint) renumber(mapping []nodeid) { 114 c.dst = mapping[c.dst] 115 c.src = mapping[c.src] 116 } 117 118 // dst = src.(typ) where typ is a concrete type 119 // A complex constraint attached to src (the interface). 120 // 121 // If exact, only tagged objects identical to typ are untagged. 122 // If !exact, tagged objects assignable to typ are untagged too. 123 // The latter is needed for various reflect operators, e.g. Send. 124 // 125 // This entails a representation change: 126 // pts(src) contains tagged objects, 127 // pts(dst) contains their payloads. 128 type untagConstraint struct { 129 typ types.Type // a concrete type 130 dst nodeid 131 src nodeid // (ptr) 132 exact bool 133 } 134 135 func (c *untagConstraint) ptr() nodeid { return c.src } 136 func (c *untagConstraint) renumber(mapping []nodeid) { 137 c.dst = mapping[c.dst] 138 c.src = mapping[c.src] 139 } 140 141 // src.method(params...) 142 // A complex constraint attached to iface. 143 type invokeConstraint struct { 144 method *types.Func // the abstract method 145 iface nodeid // (ptr) the interface 146 params nodeid // the start of the identity/params/results block 147 } 148 149 func (c *invokeConstraint) ptr() nodeid { return c.iface } 150 func (c *invokeConstraint) renumber(mapping []nodeid) { 151 c.iface = mapping[c.iface] 152 c.params = mapping[c.params] 153 }