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