--- /dev/null
+// 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 pointer
+
+import "go/types"
+
+type constraint interface {
+ // For a complex constraint, returns the nodeid of the pointer
+ // to which it is attached. For addr and copy, returns dst.
+ ptr() nodeid
+
+ // renumber replaces each nodeid n in the constraint by mapping[n].
+ renumber(mapping []nodeid)
+
+ // presolve is a hook for constraint-specific behaviour during
+ // pre-solver optimization. Typical implementations mark as
+ // indirect the set of nodes to which the solver will add copy
+ // edges or PTS labels.
+ presolve(h *hvn)
+
+ // solve is called for complex constraints when the pts for
+ // the node to which they are attached has changed.
+ solve(a *analysis, delta *nodeset)
+
+ String() string
+}
+
+// dst = &src
+// pts(dst) ⊇ {src}
+// A base constraint used to initialize the solver's pt sets
+type addrConstraint struct {
+ dst nodeid // (ptr)
+ src nodeid
+}
+
+func (c *addrConstraint) ptr() nodeid { return c.dst }
+func (c *addrConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src
+// A simple constraint represented directly as a copyTo graph edge.
+type copyConstraint struct {
+ dst nodeid // (ptr)
+ src nodeid
+}
+
+func (c *copyConstraint) ptr() nodeid { return c.dst }
+func (c *copyConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src[offset]
+// A complex constraint attached to src (the pointer)
+type loadConstraint struct {
+ offset uint32
+ dst nodeid
+ src nodeid // (ptr)
+}
+
+func (c *loadConstraint) ptr() nodeid { return c.src }
+func (c *loadConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst[offset] = src
+// A complex constraint attached to dst (the pointer)
+type storeConstraint struct {
+ offset uint32
+ dst nodeid // (ptr)
+ src nodeid
+}
+
+func (c *storeConstraint) ptr() nodeid { return c.dst }
+func (c *storeConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = &src.f or dst = &src[0]
+// A complex constraint attached to dst (the pointer)
+type offsetAddrConstraint struct {
+ offset uint32
+ dst nodeid
+ src nodeid // (ptr)
+}
+
+func (c *offsetAddrConstraint) ptr() nodeid { return c.src }
+func (c *offsetAddrConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src.(typ) where typ is an interface
+// A complex constraint attached to src (the interface).
+// No representation change: pts(dst) and pts(src) contains tagged objects.
+type typeFilterConstraint struct {
+ typ types.Type // an interface type
+ dst nodeid
+ src nodeid // (ptr)
+}
+
+func (c *typeFilterConstraint) ptr() nodeid { return c.src }
+func (c *typeFilterConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// dst = src.(typ) where typ is a concrete type
+// A complex constraint attached to src (the interface).
+//
+// If exact, only tagged objects identical to typ are untagged.
+// If !exact, tagged objects assignable to typ are untagged too.
+// The latter is needed for various reflect operators, e.g. Send.
+//
+// This entails a representation change:
+// pts(src) contains tagged objects,
+// pts(dst) contains their payloads.
+type untagConstraint struct {
+ typ types.Type // a concrete type
+ dst nodeid
+ src nodeid // (ptr)
+ exact bool
+}
+
+func (c *untagConstraint) ptr() nodeid { return c.src }
+func (c *untagConstraint) renumber(mapping []nodeid) {
+ c.dst = mapping[c.dst]
+ c.src = mapping[c.src]
+}
+
+// src.method(params...)
+// A complex constraint attached to iface.
+type invokeConstraint struct {
+ method *types.Func // the abstract method
+ iface nodeid // (ptr) the interface
+ params nodeid // the start of the identity/params/results block
+}
+
+func (c *invokeConstraint) ptr() nodeid { return c.iface }
+func (c *invokeConstraint) renumber(mapping []nodeid) {
+ c.iface = mapping[c.iface]
+ c.params = mapping[c.params]
+}