GoPLS Viewer

Home|gopls/go/pointer/reflect.go
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
5package pointer
6
7// This file implements the generation and resolution rules for
8// constraints arising from the use of reflection in the target
9// program.  See doc.go for explanation of the representation.
10//
11// For consistency, the names of all parameters match those of the
12// actual functions in the "reflect" package.
13//
14// To avoid proliferation of equivalent labels, intrinsics should
15// memoize as much as possible, like TypeOf and Zero do for their
16// tagged objects.
17//
18// TODO(adonovan): this file is rather subtle.  Explain how we derive
19// the implementation of each reflect operator from its spec,
20// including the subtleties of reflect.flag{Addr,RO,Indir}.
21// [Hint: our implementation is as if reflect.flagIndir was always
22// true, i.e. reflect.Values are pointers to tagged objects, there is
23// no inline allocation optimization; and indirect tagged objects (not
24// yet implemented) correspond to reflect.Values with
25// reflect.flagAddr.]
26// A picture would help too.
27//
28// TODO(adonovan): try factoring up the common parts of the majority of
29// these constraints that are single input, single output.
30
31import (
32    "fmt"
33    "go/constant"
34    "go/types"
35    "reflect"
36
37    "golang.org/x/tools/go/ssa"
38)
39
40func init() {
41    for namefn := range map[string]intrinsic{
42        // reflect.Value methods.
43        "(reflect.Value).Addr":            ext۰reflect۰Value۰Addr,
44        "(reflect.Value).Bool":            ext۰NoEffect,
45        "(reflect.Value).Bytes":           ext۰reflect۰Value۰Bytes,
46        "(reflect.Value).Call":            ext۰reflect۰Value۰Call,
47        "(reflect.Value).CallSlice":       ext۰reflect۰Value۰CallSlice,
48        "(reflect.Value).CanAddr":         ext۰NoEffect,
49        "(reflect.Value).CanInterface":    ext۰NoEffect,
50        "(reflect.Value).CanSet":          ext۰NoEffect,
51        "(reflect.Value).Cap":             ext۰NoEffect,
52        "(reflect.Value).Close":           ext۰NoEffect,
53        "(reflect.Value).Complex":         ext۰NoEffect,
54        "(reflect.Value).Convert":         ext۰reflect۰Value۰Convert,
55        "(reflect.Value).Elem":            ext۰reflect۰Value۰Elem,
56        "(reflect.Value).Field":           ext۰reflect۰Value۰Field,
57        "(reflect.Value).FieldByIndex":    ext۰reflect۰Value۰FieldByIndex,
58        "(reflect.Value).FieldByName":     ext۰reflect۰Value۰FieldByName,
59        "(reflect.Value).FieldByNameFunc"ext۰reflect۰Value۰FieldByNameFunc,
60        "(reflect.Value).Float":           ext۰NoEffect,
61        "(reflect.Value).Index":           ext۰reflect۰Value۰Index,
62        "(reflect.Value).Int":             ext۰NoEffect,
63        "(reflect.Value).Interface":       ext۰reflect۰Value۰Interface,
64        "(reflect.Value).InterfaceData":   ext۰NoEffect,
65        "(reflect.Value).IsNil":           ext۰NoEffect,
66        "(reflect.Value).IsValid":         ext۰NoEffect,
67        "(reflect.Value).Kind":            ext۰NoEffect,
68        "(reflect.Value).Len":             ext۰NoEffect,
69        "(reflect.Value).MapIndex":        ext۰reflect۰Value۰MapIndex,
70        "(reflect.Value).MapKeys":         ext۰reflect۰Value۰MapKeys,
71        "(reflect.Value).Method":          ext۰reflect۰Value۰Method,
72        "(reflect.Value).MethodByName":    ext۰reflect۰Value۰MethodByName,
73        "(reflect.Value).NumField":        ext۰NoEffect,
74        "(reflect.Value).NumMethod":       ext۰NoEffect,
75        "(reflect.Value).OverflowComplex"ext۰NoEffect,
76        "(reflect.Value).OverflowFloat":   ext۰NoEffect,
77        "(reflect.Value).OverflowInt":     ext۰NoEffect,
78        "(reflect.Value).OverflowUint":    ext۰NoEffect,
79        "(reflect.Value).Pointer":         ext۰NoEffect,
80        "(reflect.Value).Recv":            ext۰reflect۰Value۰Recv,
81        "(reflect.Value).Send":            ext۰reflect۰Value۰Send,
82        "(reflect.Value).Set":             ext۰reflect۰Value۰Set,
83        "(reflect.Value).SetBool":         ext۰NoEffect,
84        "(reflect.Value).SetBytes":        ext۰reflect۰Value۰SetBytes,
85        "(reflect.Value).SetComplex":      ext۰NoEffect,
86        "(reflect.Value).SetFloat":        ext۰NoEffect,
87        "(reflect.Value).SetInt":          ext۰NoEffect,
88        "(reflect.Value).SetLen":          ext۰NoEffect,
89        "(reflect.Value).SetMapIndex":     ext۰reflect۰Value۰SetMapIndex,
90        "(reflect.Value).SetPointer":      ext۰reflect۰Value۰SetPointer,
91        "(reflect.Value).SetString":       ext۰NoEffect,
92        "(reflect.Value).SetUint":         ext۰NoEffect,
93        "(reflect.Value).Slice":           ext۰reflect۰Value۰Slice,
94        "(reflect.Value).String":          ext۰NoEffect,
95        "(reflect.Value).TryRecv":         ext۰reflect۰Value۰Recv,
96        "(reflect.Value).TrySend":         ext۰reflect۰Value۰Send,
97        "(reflect.Value).Type":            ext۰NoEffect,
98        "(reflect.Value).Uint":            ext۰NoEffect,
99        "(reflect.Value).UnsafeAddr":      ext۰NoEffect,
100
101        // Standalone reflect.* functions.
102        "reflect.Append":      ext۰reflect۰Append,
103        "reflect.AppendSlice"ext۰reflect۰AppendSlice,
104        "reflect.Copy":        ext۰reflect۰Copy,
105        "reflect.ChanOf":      ext۰reflect۰ChanOf,
106        "reflect.DeepEqual":   ext۰NoEffect,
107        "reflect.Indirect":    ext۰reflect۰Indirect,
108        "reflect.MakeChan":    ext۰reflect۰MakeChan,
109        "reflect.MakeFunc":    ext۰reflect۰MakeFunc,
110        "reflect.MakeMap":     ext۰reflect۰MakeMap,
111        "reflect.MakeSlice":   ext۰reflect۰MakeSlice,
112        "reflect.MapOf":       ext۰reflect۰MapOf,
113        "reflect.New":         ext۰reflect۰New,
114        "reflect.NewAt":       ext۰reflect۰NewAt,
115        "reflect.PtrTo":       ext۰reflect۰PtrTo,
116        "reflect.Select":      ext۰reflect۰Select,
117        "reflect.SliceOf":     ext۰reflect۰SliceOf,
118        "reflect.TypeOf":      ext۰reflect۰TypeOf,
119        "reflect.ValueOf":     ext۰reflect۰ValueOf,
120        "reflect.Zero":        ext۰reflect۰Zero,
121        "reflect.init":        ext۰NoEffect,
122
123        // *reflect.rtype methods
124        "(*reflect.rtype).Align":           ext۰NoEffect,
125        "(*reflect.rtype).AssignableTo":    ext۰NoEffect,
126        "(*reflect.rtype).Bits":            ext۰NoEffect,
127        "(*reflect.rtype).ChanDir":         ext۰NoEffect,
128        "(*reflect.rtype).ConvertibleTo":   ext۰NoEffect,
129        "(*reflect.rtype).Elem":            ext۰reflect۰rtype۰Elem,
130        "(*reflect.rtype).Field":           ext۰reflect۰rtype۰Field,
131        "(*reflect.rtype).FieldAlign":      ext۰NoEffect,
132        "(*reflect.rtype).FieldByIndex":    ext۰reflect۰rtype۰FieldByIndex,
133        "(*reflect.rtype).FieldByName":     ext۰reflect۰rtype۰FieldByName,
134        "(*reflect.rtype).FieldByNameFunc"ext۰reflect۰rtype۰FieldByNameFunc,
135        "(*reflect.rtype).Implements":      ext۰NoEffect,
136        "(*reflect.rtype).In":              ext۰reflect۰rtype۰In,
137        "(*reflect.rtype).IsVariadic":      ext۰NoEffect,
138        "(*reflect.rtype).Key":             ext۰reflect۰rtype۰Key,
139        "(*reflect.rtype).Kind":            ext۰NoEffect,
140        "(*reflect.rtype).Len":             ext۰NoEffect,
141        "(*reflect.rtype).Method":          ext۰reflect۰rtype۰Method,
142        "(*reflect.rtype).MethodByName":    ext۰reflect۰rtype۰MethodByName,
143        "(*reflect.rtype).Name":            ext۰NoEffect,
144        "(*reflect.rtype).NumField":        ext۰NoEffect,
145        "(*reflect.rtype).NumIn":           ext۰NoEffect,
146        "(*reflect.rtype).NumMethod":       ext۰NoEffect,
147        "(*reflect.rtype).NumOut":          ext۰NoEffect,
148        "(*reflect.rtype).Out":             ext۰reflect۰rtype۰Out,
149        "(*reflect.rtype).PkgPath":         ext۰NoEffect,
150        "(*reflect.rtype).Size":            ext۰NoEffect,
151        "(*reflect.rtype).String":          ext۰NoEffect,
152    } {
153        intrinsicsByName[name] = fn
154    }
155}
156
157// -------------------- (reflect.Value) --------------------
158
159func ext۰reflect۰Value۰Addr(a *analysiscgn *cgnode) {} // TODO(adonovan)
160
161// ---------- func (Value).Bytes() Value ----------
162
163// result = v.Bytes()
164type rVBytesConstraint struct {
165    v      nodeid // (ptr)
166    result nodeid // (indirect)
167}
168
169func (c *rVBytesConstraintptr() nodeid { return c.v }
170func (c *rVBytesConstraintpresolve(h *hvn) {
171    h.markIndirect(onodeid(c.result), "rVBytes.result")
172}
173func (c *rVBytesConstraintrenumber(mapping []nodeid) {
174    c.v = mapping[c.v]
175    c.result = mapping[c.result]
176}
177
178func (c *rVBytesConstraintString() string {
179    return fmt.Sprintf("n%d = reflect n%d.Bytes()"c.resultc.v)
180}
181
182func (c *rVBytesConstraintsolve(a *analysisdelta *nodeset) {
183    changed := false
184    for _x := range delta.AppendTo(a.deltaSpace) {
185        vObj := nodeid(x)
186        tDynsliceindirect := a.taggedValue(vObj)
187        if indirect {
188            // TODO(adonovan): we'll need to implement this
189            // when we start creating indirect tagged objects.
190            panic("indirect tagged object")
191        }
192
193        tSliceok := tDyn.Underlying().(*types.Slice)
194        if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
195            if a.onlineCopy(c.resultslice) {
196                changed = true
197            }
198        }
199    }
200    if changed {
201        a.addWork(c.result)
202    }
203}
204
205func ext۰reflect۰Value۰Bytes(a *analysiscgn *cgnode) {
206    a.addConstraint(&rVBytesConstraint{
207        v:      a.funcParams(cgn.obj),
208        resulta.funcResults(cgn.obj),
209    })
210}
211
212// ---------- func (Value).Call(in []Value) []Value ----------
213
214// result = v.Call(in)
215type rVCallConstraint struct {
216    cgn       *cgnode
217    targets   nodeid // (indirect)
218    v         nodeid // (ptr)
219    arg       nodeid // = in[*]
220    result    nodeid // (indirect)
221    dotdotdot bool   // interpret last arg as a "..." slice
222}
223
224func (c *rVCallConstraintptr() nodeid { return c.v }
225func (c *rVCallConstraintpresolve(h *hvn) {
226    h.markIndirect(onodeid(c.targets), "rVCall.targets")
227    h.markIndirect(onodeid(c.result), "rVCall.result")
228}
229func (c *rVCallConstraintrenumber(mapping []nodeid) {
230    c.targets = mapping[c.targets]
231    c.v = mapping[c.v]
232    c.arg = mapping[c.arg]
233    c.result = mapping[c.result]
234}
235
236func (c *rVCallConstraintString() string {
237    return fmt.Sprintf("n%d = reflect n%d.Call(n%d)"c.resultc.vc.arg)
238}
239
240func (c *rVCallConstraintsolve(a *analysisdelta *nodeset) {
241    if c.targets == 0 {
242        panic("no targets")
243    }
244
245    changed := false
246    for _x := range delta.AppendTo(a.deltaSpace) {
247        vObj := nodeid(x)
248        tDynfnindirect := a.taggedValue(vObj)
249        if indirect {
250            // TODO(adonovan): we'll need to implement this
251            // when we start creating indirect tagged objects.
252            panic("indirect tagged object")
253        }
254
255        tSigok := tDyn.Underlying().(*types.Signature)
256        if !ok {
257            continue // not a function
258        }
259        if tSig.Recv() != nil {
260            panic(tSig// TODO(adonovan): rethink when we implement Method()
261        }
262
263        // Add dynamic call target.
264        if a.onlineCopy(c.targetsfn) {
265            a.addWork(c.targets)
266            // TODO(adonovan): is 'else continue' a sound optimisation here?
267        }
268
269        // Allocate a P/R block.
270        tParams := tSig.Params()
271        tResults := tSig.Results()
272        params := a.addNodes(tParams"rVCall.params")
273        results := a.addNodes(tResults"rVCall.results")
274
275        // Make a dynamic call to 'fn'.
276        a.store(fnparams1a.sizeof(tParams))
277        a.load(resultsfn1+a.sizeof(tParams), a.sizeof(tResults))
278
279        // Populate P by type-asserting each actual arg (all merged in c.arg).
280        for in := 0tParams.Len(); i < ni++ {
281            T := tParams.At(i).Type()
282            a.typeAssert(Tparamsc.argfalse)
283            params += nodeid(a.sizeof(T))
284        }
285
286        // Use R by tagging and copying each actual result to c.result.
287        for in := 0tResults.Len(); i < ni++ {
288            T := tResults.At(i).Type()
289            // Convert from an arbitrary type to a reflect.Value
290            // (like MakeInterface followed by reflect.ValueOf).
291            if isInterface(T) {
292                // (don't tag)
293                if a.onlineCopy(c.resultresults) {
294                    changed = true
295                }
296            } else {
297                obj := a.makeTagged(Tc.cgnnil)
298                a.onlineCopyN(obj+1resultsa.sizeof(T))
299                if a.addLabel(c.resultobj) { // (true)
300                    changed = true
301                }
302            }
303            results += nodeid(a.sizeof(T))
304        }
305    }
306    if changed {
307        a.addWork(c.result)
308    }
309}
310
311// Common code for direct (inlined) and indirect calls to (reflect.Value).Call.
312func reflectCallImpl(a *analysiscgn *cgnodesite *callsiterecvarg nodeiddotdotdot boolnodeid {
313    // Allocate []reflect.Value array for the result.
314    ret := a.nextNode()
315    a.addNodes(types.NewArray(a.reflectValueObj.Type(), 1), "rVCall.ret")
316    a.endObject(retcgnnil)
317
318    // pts(targets) will be the set of possible call targets.
319    site.targets = a.addOneNode(tInvalid"rvCall.targets"nil)
320
321    // All arguments are merged since they arrive in a slice.
322    argelts := a.addOneNode(a.reflectValueObj.Type(), "rVCall.args"nil)
323    a.load(argeltsarg11// slice elements
324
325    a.addConstraint(&rVCallConstraint{
326        cgn:       cgn,
327        targets:   site.targets,
328        v:         recv,
329        arg:       argelts,
330        result:    ret + 1// results go into elements of ret
331        dotdotdotdotdotdot,
332    })
333    return ret
334}
335
336func reflectCall(a *analysiscgn *cgnodedotdotdot bool) {
337    // This is the shared contour implementation of (reflect.Value).Call
338    // and CallSlice, as used by indirect calls (rare).
339    // Direct calls are inlined in gen.go, eliding the
340    // intermediate cgnode for Call.
341    site := new(callsite)
342    cgn.sites = append(cgn.sitessite)
343    recv := a.funcParams(cgn.obj)
344    arg := recv + 1
345    ret := reflectCallImpl(acgnsiterecvargdotdotdot)
346    a.addressOf(cgn.fn.Signature.Results().At(0).Type(), a.funcResults(cgn.obj), ret)
347}
348
349func ext۰reflect۰Value۰Call(a *analysiscgn *cgnode) {
350    reflectCall(acgnfalse)
351}
352
353func ext۰reflect۰Value۰CallSlice(a *analysiscgn *cgnode) {
354    // TODO(adonovan): implement.  Also, inline direct calls in gen.go too.
355    if false {
356        reflectCall(acgntrue)
357    }
358}
359
360func ext۰reflect۰Value۰Convert(a *analysiscgn *cgnode) {} // TODO(adonovan)
361
362// ---------- func (Value).Elem() Value ----------
363
364// result = v.Elem()
365type rVElemConstraint struct {
366    cgn    *cgnode
367    v      nodeid // (ptr)
368    result nodeid // (indirect)
369}
370
371func (c *rVElemConstraintptr() nodeid { return c.v }
372func (c *rVElemConstraintpresolve(h *hvn) {
373    h.markIndirect(onodeid(c.result), "rVElem.result")
374}
375func (c *rVElemConstraintrenumber(mapping []nodeid) {
376    c.v = mapping[c.v]
377    c.result = mapping[c.result]
378}
379
380func (c *rVElemConstraintString() string {
381    return fmt.Sprintf("n%d = reflect n%d.Elem()"c.resultc.v)
382}
383
384func (c *rVElemConstraintsolve(a *analysisdelta *nodeset) {
385    changed := false
386    for _x := range delta.AppendTo(a.deltaSpace) {
387        vObj := nodeid(x)
388        tDynpayloadindirect := a.taggedValue(vObj)
389        if indirect {
390            // TODO(adonovan): we'll need to implement this
391            // when we start creating indirect tagged objects.
392            panic("indirect tagged object")
393        }
394
395        switch t := tDyn.Underlying().(type) {
396        case *types.Interface:
397            if a.onlineCopy(c.resultpayload) {
398                changed = true
399            }
400
401        case *types.Pointer:
402            obj := a.makeTagged(t.Elem(), c.cgnnil)
403            a.load(obj+1payload0a.sizeof(t.Elem()))
404            if a.addLabel(c.resultobj) {
405                changed = true
406            }
407        }
408    }
409    if changed {
410        a.addWork(c.result)
411    }
412}
413
414func ext۰reflect۰Value۰Elem(a *analysiscgn *cgnode) {
415    a.addConstraint(&rVElemConstraint{
416        cgn:    cgn,
417        v:      a.funcParams(cgn.obj),
418        resulta.funcResults(cgn.obj),
419    })
420}
421
422func ext۰reflect۰Value۰Field(a *analysiscgn *cgnode)           {} // TODO(adonovan)
423func ext۰reflect۰Value۰FieldByIndex(a *analysiscgn *cgnode)    {} // TODO(adonovan)
424func ext۰reflect۰Value۰FieldByName(a *analysiscgn *cgnode)     {} // TODO(adonovan)
425func ext۰reflect۰Value۰FieldByNameFunc(a *analysiscgn *cgnode) {} // TODO(adonovan)
426
427// ---------- func (Value).Index() Value ----------
428
429// result = v.Index()
430type rVIndexConstraint struct {
431    cgn    *cgnode
432    v      nodeid // (ptr)
433    result nodeid // (indirect)
434}
435
436func (c *rVIndexConstraintptr() nodeid { return c.v }
437func (c *rVIndexConstraintpresolve(h *hvn) {
438    h.markIndirect(onodeid(c.result), "rVIndex.result")
439}
440func (c *rVIndexConstraintrenumber(mapping []nodeid) {
441    c.v = mapping[c.v]
442    c.result = mapping[c.result]
443}
444
445func (c *rVIndexConstraintString() string {
446    return fmt.Sprintf("n%d = reflect n%d.Index()"c.resultc.v)
447}
448
449func (c *rVIndexConstraintsolve(a *analysisdelta *nodeset) {
450    changed := false
451    for _x := range delta.AppendTo(a.deltaSpace) {
452        vObj := nodeid(x)
453        tDynpayloadindirect := a.taggedValue(vObj)
454        if indirect {
455            // TODO(adonovan): we'll need to implement this
456            // when we start creating indirect tagged objects.
457            panic("indirect tagged object")
458        }
459
460        var res nodeid
461        switch t := tDyn.Underlying().(type) {
462        case *types.Array:
463            res = a.makeTagged(t.Elem(), c.cgnnil)
464            a.onlineCopyN(res+1payload+1a.sizeof(t.Elem()))
465
466        case *types.Slice:
467            res = a.makeTagged(t.Elem(), c.cgnnil)
468            a.load(res+1payload1a.sizeof(t.Elem()))
469
470        case *types.Basic:
471            if t.Kind() == types.String {
472                res = a.makeTagged(types.Typ[types.Rune], c.cgnnil)
473            }
474        }
475        if res != 0 && a.addLabel(c.resultres) {
476            changed = true
477        }
478    }
479    if changed {
480        a.addWork(c.result)
481    }
482}
483
484func ext۰reflect۰Value۰Index(a *analysiscgn *cgnode) {
485    a.addConstraint(&rVIndexConstraint{
486        cgn:    cgn,
487        v:      a.funcParams(cgn.obj),
488        resulta.funcResults(cgn.obj),
489    })
490}
491
492// ---------- func (Value).Interface() Value ----------
493
494// result = v.Interface()
495type rVInterfaceConstraint struct {
496    v      nodeid // (ptr)
497    result nodeid // (indirect)
498}
499
500func (c *rVInterfaceConstraintptr() nodeid { return c.v }
501func (c *rVInterfaceConstraintpresolve(h *hvn) {
502    h.markIndirect(onodeid(c.result), "rVInterface.result")
503}
504func (c *rVInterfaceConstraintrenumber(mapping []nodeid) {
505    c.v = mapping[c.v]
506    c.result = mapping[c.result]
507}
508
509func (c *rVInterfaceConstraintString() string {
510    return fmt.Sprintf("n%d = reflect n%d.Interface()"c.resultc.v)
511}
512
513func (c *rVInterfaceConstraintsolve(a *analysisdelta *nodeset) {
514    changed := false
515    for _x := range delta.AppendTo(a.deltaSpace) {
516        vObj := nodeid(x)
517        tDynpayloadindirect := a.taggedValue(vObj)
518        if indirect {
519            // TODO(adonovan): we'll need to implement this
520            // when we start creating indirect tagged objects.
521            panic("indirect tagged object")
522        }
523
524        if isInterface(tDyn) {
525            if a.onlineCopy(c.resultpayload) {
526                a.addWork(c.result)
527            }
528        } else {
529            if a.addLabel(c.resultvObj) {
530                changed = true
531            }
532        }
533    }
534    if changed {
535        a.addWork(c.result)
536    }
537}
538
539func ext۰reflect۰Value۰Interface(a *analysiscgn *cgnode) {
540    a.addConstraint(&rVInterfaceConstraint{
541        v:      a.funcParams(cgn.obj),
542        resulta.funcResults(cgn.obj),
543    })
544}
545
546// ---------- func (Value).MapIndex(Value) Value ----------
547
548// result = v.MapIndex(_)
549type rVMapIndexConstraint struct {
550    cgn    *cgnode
551    v      nodeid // (ptr)
552    result nodeid // (indirect)
553}
554
555func (c *rVMapIndexConstraintptr() nodeid { return c.v }
556func (c *rVMapIndexConstraintpresolve(h *hvn) {
557    h.markIndirect(onodeid(c.result), "rVMapIndex.result")
558}
559func (c *rVMapIndexConstraintrenumber(mapping []nodeid) {
560    c.v = mapping[c.v]
561    c.result = mapping[c.result]
562}
563
564func (c *rVMapIndexConstraintString() string {
565    return fmt.Sprintf("n%d = reflect n%d.MapIndex(_)"c.resultc.v)
566}
567
568func (c *rVMapIndexConstraintsolve(a *analysisdelta *nodeset) {
569    changed := false
570    for _x := range delta.AppendTo(a.deltaSpace) {
571        vObj := nodeid(x)
572        tDynmindirect := a.taggedValue(vObj)
573        tMap_ := tDyn.Underlying().(*types.Map)
574        if tMap == nil {
575            continue // not a map
576        }
577        if indirect {
578            // TODO(adonovan): we'll need to implement this
579            // when we start creating indirect tagged objects.
580            panic("indirect tagged object")
581        }
582
583        obj := a.makeTagged(tMap.Elem(), c.cgnnil)
584        a.load(obj+1ma.sizeof(tMap.Key()), a.sizeof(tMap.Elem()))
585        if a.addLabel(c.resultobj) {
586            changed = true
587        }
588    }
589    if changed {
590        a.addWork(c.result)
591    }
592}
593
594func ext۰reflect۰Value۰MapIndex(a *analysiscgn *cgnode) {
595    a.addConstraint(&rVMapIndexConstraint{
596        cgn:    cgn,
597        v:      a.funcParams(cgn.obj),
598        resulta.funcResults(cgn.obj),
599    })
600}
601
602// ---------- func (Value).MapKeys() []Value ----------
603
604// result = v.MapKeys()
605type rVMapKeysConstraint struct {
606    cgn    *cgnode
607    v      nodeid // (ptr)
608    result nodeid // (indirect)
609}
610
611func (c *rVMapKeysConstraintptr() nodeid { return c.v }
612func (c *rVMapKeysConstraintpresolve(h *hvn) {
613    h.markIndirect(onodeid(c.result), "rVMapKeys.result")
614}
615func (c *rVMapKeysConstraintrenumber(mapping []nodeid) {
616    c.v = mapping[c.v]
617    c.result = mapping[c.result]
618}
619
620func (c *rVMapKeysConstraintString() string {
621    return fmt.Sprintf("n%d = reflect n%d.MapKeys()"c.resultc.v)
622}
623
624func (c *rVMapKeysConstraintsolve(a *analysisdelta *nodeset) {
625    changed := false
626    for _x := range delta.AppendTo(a.deltaSpace) {
627        vObj := nodeid(x)
628        tDynmindirect := a.taggedValue(vObj)
629        tMap_ := tDyn.Underlying().(*types.Map)
630        if tMap == nil {
631            continue // not a map
632        }
633        if indirect {
634            // TODO(adonovan): we'll need to implement this
635            // when we start creating indirect tagged objects.
636            panic("indirect tagged object")
637        }
638
639        kObj := a.makeTagged(tMap.Key(), c.cgnnil)
640        a.load(kObj+1m0a.sizeof(tMap.Key()))
641        if a.addLabel(c.resultkObj) {
642            changed = true
643        }
644    }
645    if changed {
646        a.addWork(c.result)
647    }
648}
649
650func ext۰reflect۰Value۰MapKeys(a *analysiscgn *cgnode) {
651    // Allocate an array for the result.
652    obj := a.nextNode()
653    T := types.NewSlice(a.reflectValueObj.Type())
654    a.addNodes(sliceToArray(T), "reflect.MapKeys result")
655    a.endObject(objcgnnil)
656    a.addressOf(Ta.funcResults(cgn.obj), obj)
657
658    a.addConstraint(&rVMapKeysConstraint{
659        cgn:    cgn,
660        v:      a.funcParams(cgn.obj),
661        resultobj + 1// result is stored in array elems
662    })
663}
664
665func ext۰reflect۰Value۰Method(a *analysiscgn *cgnode)       {} // TODO(adonovan)
666func ext۰reflect۰Value۰MethodByName(a *analysiscgn *cgnode) {} // TODO(adonovan)
667
668// ---------- func (Value).Recv(Value) Value ----------
669
670// result, _ = v.Recv()
671type rVRecvConstraint struct {
672    cgn    *cgnode
673    v      nodeid // (ptr)
674    result nodeid // (indirect)
675}
676
677func (c *rVRecvConstraintptr() nodeid { return c.v }
678func (c *rVRecvConstraintpresolve(h *hvn) {
679    h.markIndirect(onodeid(c.result), "rVRecv.result")
680}
681func (c *rVRecvConstraintrenumber(mapping []nodeid) {
682    c.v = mapping[c.v]
683    c.result = mapping[c.result]
684}
685
686func (c *rVRecvConstraintString() string {
687    return fmt.Sprintf("n%d = reflect n%d.Recv()"c.resultc.v)
688}
689
690func (c *rVRecvConstraintsolve(a *analysisdelta *nodeset) {
691    changed := false
692    for _x := range delta.AppendTo(a.deltaSpace) {
693        vObj := nodeid(x)
694        tDynchindirect := a.taggedValue(vObj)
695        tChan_ := tDyn.Underlying().(*types.Chan)
696        if tChan == nil {
697            continue // not a channel
698        }
699        if indirect {
700            // TODO(adonovan): we'll need to implement this
701            // when we start creating indirect tagged objects.
702            panic("indirect tagged object")
703        }
704
705        tElem := tChan.Elem()
706        elemObj := a.makeTagged(tElemc.cgnnil)
707        a.load(elemObj+1ch0a.sizeof(tElem))
708        if a.addLabel(c.resultelemObj) {
709            changed = true
710        }
711    }
712    if changed {
713        a.addWork(c.result)
714    }
715}
716
717func ext۰reflect۰Value۰Recv(a *analysiscgn *cgnode) {
718    a.addConstraint(&rVRecvConstraint{
719        cgn:    cgn,
720        v:      a.funcParams(cgn.obj),
721        resulta.funcResults(cgn.obj),
722    })
723}
724
725// ---------- func (Value).Send(Value) ----------
726
727// v.Send(x)
728type rVSendConstraint struct {
729    cgn *cgnode
730    v   nodeid // (ptr)
731    x   nodeid
732}
733
734func (c *rVSendConstraintptr() nodeid   { return c.v }
735func (c *rVSendConstraintpresolve(*hvn) {}
736func (c *rVSendConstraintrenumber(mapping []nodeid) {
737    c.v = mapping[c.v]
738    c.x = mapping[c.x]
739}
740
741func (c *rVSendConstraintString() string {
742    return fmt.Sprintf("reflect n%d.Send(n%d)"c.vc.x)
743}
744
745func (c *rVSendConstraintsolve(a *analysisdelta *nodeset) {
746    for _x := range delta.AppendTo(a.deltaSpace) {
747        vObj := nodeid(x)
748        tDynchindirect := a.taggedValue(vObj)
749        tChan_ := tDyn.Underlying().(*types.Chan)
750        if tChan == nil {
751            continue // not a channel
752        }
753        if indirect {
754            // TODO(adonovan): we'll need to implement this
755            // when we start creating indirect tagged objects.
756            panic("indirect tagged object")
757        }
758
759        // Extract x's payload to xtmp, then store to channel.
760        tElem := tChan.Elem()
761        xtmp := a.addNodes(tElem"Send.xtmp")
762        a.typeAssert(tElemxtmpc.xfalse)
763        a.store(chxtmp0a.sizeof(tElem))
764    }
765}
766
767func ext۰reflect۰Value۰Send(a *analysiscgn *cgnode) {
768    params := a.funcParams(cgn.obj)
769    a.addConstraint(&rVSendConstraint{
770        cgncgn,
771        v:   params,
772        x:   params + 1,
773    })
774}
775
776func ext۰reflect۰Value۰Set(a *analysiscgn *cgnode) {} // TODO(adonovan)
777
778// ---------- func (Value).SetBytes(x []byte) ----------
779
780// v.SetBytes(x)
781type rVSetBytesConstraint struct {
782    cgn *cgnode
783    v   nodeid // (ptr)
784    x   nodeid
785}
786
787func (c *rVSetBytesConstraintptr() nodeid   { return c.v }
788func (c *rVSetBytesConstraintpresolve(*hvn) {}
789func (c *rVSetBytesConstraintrenumber(mapping []nodeid) {
790    c.v = mapping[c.v]
791    c.x = mapping[c.x]
792}
793
794func (c *rVSetBytesConstraintString() string {
795    return fmt.Sprintf("reflect n%d.SetBytes(n%d)"c.vc.x)
796}
797
798func (c *rVSetBytesConstraintsolve(a *analysisdelta *nodeset) {
799    for _x := range delta.AppendTo(a.deltaSpace) {
800        vObj := nodeid(x)
801        tDynsliceindirect := a.taggedValue(vObj)
802        if indirect {
803            // TODO(adonovan): we'll need to implement this
804            // when we start creating indirect tagged objects.
805            panic("indirect tagged object")
806        }
807
808        tSliceok := tDyn.Underlying().(*types.Slice)
809        if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
810            if a.onlineCopy(slicec.x) {
811                a.addWork(slice)
812            }
813        }
814    }
815}
816
817func ext۰reflect۰Value۰SetBytes(a *analysiscgn *cgnode) {
818    params := a.funcParams(cgn.obj)
819    a.addConstraint(&rVSetBytesConstraint{
820        cgncgn,
821        v:   params,
822        x:   params + 1,
823    })
824}
825
826// ---------- func (Value).SetMapIndex(k Value, v Value) ----------
827
828// v.SetMapIndex(key, val)
829type rVSetMapIndexConstraint struct {
830    cgn *cgnode
831    v   nodeid // (ptr)
832    key nodeid
833    val nodeid
834}
835
836func (c *rVSetMapIndexConstraintptr() nodeid   { return c.v }
837func (c *rVSetMapIndexConstraintpresolve(*hvn) {}
838func (c *rVSetMapIndexConstraintrenumber(mapping []nodeid) {
839    c.v = mapping[c.v]
840    c.key = mapping[c.key]
841    c.val = mapping[c.val]
842}
843
844func (c *rVSetMapIndexConstraintString() string {
845    return fmt.Sprintf("reflect n%d.SetMapIndex(n%d, n%d)"c.vc.keyc.val)
846}
847
848func (c *rVSetMapIndexConstraintsolve(a *analysisdelta *nodeset) {
849    for _x := range delta.AppendTo(a.deltaSpace) {
850        vObj := nodeid(x)
851        tDynmindirect := a.taggedValue(vObj)
852        tMap_ := tDyn.Underlying().(*types.Map)
853        if tMap == nil {
854            continue // not a map
855        }
856        if indirect {
857            // TODO(adonovan): we'll need to implement this
858            // when we start creating indirect tagged objects.
859            panic("indirect tagged object")
860        }
861
862        keysize := a.sizeof(tMap.Key())
863
864        // Extract key's payload to keytmp, then store to map key.
865        keytmp := a.addNodes(tMap.Key(), "SetMapIndex.keytmp")
866        a.typeAssert(tMap.Key(), keytmpc.keyfalse)
867        a.store(mkeytmp0keysize)
868
869        // Extract val's payload to vtmp, then store to map value.
870        valtmp := a.addNodes(tMap.Elem(), "SetMapIndex.valtmp")
871        a.typeAssert(tMap.Elem(), valtmpc.valfalse)
872        a.store(mvaltmpkeysizea.sizeof(tMap.Elem()))
873    }
874}
875
876func ext۰reflect۰Value۰SetMapIndex(a *analysiscgn *cgnode) {
877    params := a.funcParams(cgn.obj)
878    a.addConstraint(&rVSetMapIndexConstraint{
879        cgncgn,
880        v:   params,
881        keyparams + 1,
882        valparams + 2,
883    })
884}
885
886func ext۰reflect۰Value۰SetPointer(a *analysiscgn *cgnode) {} // TODO(adonovan)
887
888// ---------- func (Value).Slice(v Value, i, j int) Value ----------
889
890// result = v.Slice(_, _)
891type rVSliceConstraint struct {
892    cgn    *cgnode
893    v      nodeid // (ptr)
894    result nodeid // (indirect)
895}
896
897func (c *rVSliceConstraintptr() nodeid { return c.v }
898func (c *rVSliceConstraintpresolve(h *hvn) {
899    h.markIndirect(onodeid(c.result), "rVSlice.result")
900}
901func (c *rVSliceConstraintrenumber(mapping []nodeid) {
902    c.v = mapping[c.v]
903    c.result = mapping[c.result]
904}
905
906func (c *rVSliceConstraintString() string {
907    return fmt.Sprintf("n%d = reflect n%d.Slice(_, _)"c.resultc.v)
908}
909
910func (c *rVSliceConstraintsolve(a *analysisdelta *nodeset) {
911    changed := false
912    for _x := range delta.AppendTo(a.deltaSpace) {
913        vObj := nodeid(x)
914        tDynpayloadindirect := a.taggedValue(vObj)
915        if indirect {
916            // TODO(adonovan): we'll need to implement this
917            // when we start creating indirect tagged objects.
918            panic("indirect tagged object")
919        }
920
921        var res nodeid
922        switch t := tDyn.Underlying().(type) {
923        case *types.Pointer:
924            if tArrok := t.Elem().Underlying().(*types.Array); ok {
925                // pointer to array
926                res = a.makeTagged(types.NewSlice(tArr.Elem()), c.cgnnil)
927                if a.onlineCopy(res+1payload) {
928                    a.addWork(res + 1)
929                }
930            }
931
932        case *types.Array:
933            // TODO(adonovan): implement addressable
934            // arrays when we do indirect tagged objects.
935
936        case *types.Slice:
937            res = vObj
938
939        case *types.Basic:
940            if t == types.Typ[types.String] {
941                res = vObj
942            }
943        }
944
945        if res != 0 && a.addLabel(c.resultres) {
946            changed = true
947        }
948    }
949    if changed {
950        a.addWork(c.result)
951    }
952}
953
954func ext۰reflect۰Value۰Slice(a *analysiscgn *cgnode) {
955    a.addConstraint(&rVSliceConstraint{
956        cgn:    cgn,
957        v:      a.funcParams(cgn.obj),
958        resulta.funcResults(cgn.obj),
959    })
960}
961
962// -------------------- Standalone reflect functions --------------------
963
964func ext۰reflect۰Append(a *analysiscgn *cgnode)      {} // TODO(adonovan)
965func ext۰reflect۰AppendSlice(a *analysiscgn *cgnode) {} // TODO(adonovan)
966func ext۰reflect۰Copy(a *analysiscgn *cgnode)        {} // TODO(adonovan)
967
968// ---------- func ChanOf(ChanDir, Type) Type ----------
969
970// result = ChanOf(dir, t)
971type reflectChanOfConstraint struct {
972    cgn    *cgnode
973    t      nodeid // (ptr)
974    result nodeid // (indirect)
975    dirs   []types.ChanDir
976}
977
978func (c *reflectChanOfConstraintptr() nodeid { return c.t }
979func (c *reflectChanOfConstraintpresolve(h *hvn) {
980    h.markIndirect(onodeid(c.result), "reflectChanOf.result")
981}
982func (c *reflectChanOfConstraintrenumber(mapping []nodeid) {
983    c.t = mapping[c.t]
984    c.result = mapping[c.result]
985}
986
987func (c *reflectChanOfConstraintString() string {
988    return fmt.Sprintf("n%d = reflect.ChanOf(n%d)"c.resultc.t)
989}
990
991func (c *reflectChanOfConstraintsolve(a *analysisdelta *nodeset) {
992    changed := false
993    for _x := range delta.AppendTo(a.deltaSpace) {
994        tObj := nodeid(x)
995        T := a.rtypeTaggedValue(tObj)
996
997        if typeTooHigh(T) {
998            continue
999        }
1000
1001        for _dir := range c.dirs {
1002            if a.addLabel(c.resulta.makeRtype(types.NewChan(dirT))) {
1003                changed = true
1004            }
1005        }
1006    }
1007    if changed {
1008        a.addWork(c.result)
1009    }
1010}
1011
1012// dirMap maps reflect.ChanDir to the set of channel types generated by ChanOf.
1013var dirMap = [...][]types.ChanDir{
1014    0:               {types.SendOnlytypes.RecvOnlytypes.SendRecv}, // unknown
1015    reflect.RecvDir: {types.RecvOnly},
1016    reflect.SendDir: {types.SendOnly},
1017    reflect.BothDir: {types.SendRecv},
1018}
1019
1020func ext۰reflect۰ChanOf(a *analysiscgn *cgnode) {
1021    // If we have access to the callsite,
1022    // and the channel argument is a constant (as is usual),
1023    // only generate the requested direction.
1024    var dir reflect.ChanDir // unknown
1025    if site := cgn.callersitesite != nil {
1026        if cok := site.instr.Common().Args[0].(*ssa.Const); ok {
1027            v := c.Int64()
1028            if 0 <= v && v <= int64(reflect.BothDir) {
1029                dir = reflect.ChanDir(v)
1030            }
1031        }
1032    }
1033
1034    params := a.funcParams(cgn.obj)
1035    a.addConstraint(&reflectChanOfConstraint{
1036        cgn:    cgn,
1037        t:      params + 1,
1038        resulta.funcResults(cgn.obj),
1039        dirs:   dirMap[dir],
1040    })
1041}
1042
1043// ---------- func Indirect(v Value) Value ----------
1044
1045// result = Indirect(v)
1046type reflectIndirectConstraint struct {
1047    cgn    *cgnode
1048    v      nodeid // (ptr)
1049    result nodeid // (indirect)
1050}
1051
1052func (c *reflectIndirectConstraintptr() nodeid { return c.v }
1053func (c *reflectIndirectConstraintpresolve(h *hvn) {
1054    h.markIndirect(onodeid(c.result), "reflectIndirect.result")
1055}
1056func (c *reflectIndirectConstraintrenumber(mapping []nodeid) {
1057    c.v = mapping[c.v]
1058    c.result = mapping[c.result]
1059}
1060
1061func (c *reflectIndirectConstraintString() string {
1062    return fmt.Sprintf("n%d = reflect.Indirect(n%d)"c.resultc.v)
1063}
1064
1065func (c *reflectIndirectConstraintsolve(a *analysisdelta *nodeset) {
1066    changed := false
1067    for _x := range delta.AppendTo(a.deltaSpace) {
1068        vObj := nodeid(x)
1069        tDyn__ := a.taggedValue(vObj)
1070        var res nodeid
1071        if tPtrok := tDyn.Underlying().(*types.Pointer); ok {
1072            // load the payload of the pointer's tagged object
1073            // into a new tagged object
1074            res = a.makeTagged(tPtr.Elem(), c.cgnnil)
1075            a.load(res+1vObj+10a.sizeof(tPtr.Elem()))
1076        } else {
1077            res = vObj
1078        }
1079
1080        if a.addLabel(c.resultres) {
1081            changed = true
1082        }
1083    }
1084    if changed {
1085        a.addWork(c.result)
1086    }
1087}
1088
1089func ext۰reflect۰Indirect(a *analysiscgn *cgnode) {
1090    a.addConstraint(&reflectIndirectConstraint{
1091        cgn:    cgn,
1092        v:      a.funcParams(cgn.obj),
1093        resulta.funcResults(cgn.obj),
1094    })
1095}
1096
1097// ---------- func MakeChan(Type) Value ----------
1098
1099// result = MakeChan(typ)
1100type reflectMakeChanConstraint struct {
1101    cgn    *cgnode
1102    typ    nodeid // (ptr)
1103    result nodeid // (indirect)
1104}
1105
1106func (c *reflectMakeChanConstraintptr() nodeid { return c.typ }
1107func (c *reflectMakeChanConstraintpresolve(h *hvn) {
1108    h.markIndirect(onodeid(c.result), "reflectMakeChan.result")
1109}
1110func (c *reflectMakeChanConstraintrenumber(mapping []nodeid) {
1111    c.typ = mapping[c.typ]
1112    c.result = mapping[c.result]
1113}
1114
1115func (c *reflectMakeChanConstraintString() string {
1116    return fmt.Sprintf("n%d = reflect.MakeChan(n%d)"c.resultc.typ)
1117}
1118
1119func (c *reflectMakeChanConstraintsolve(a *analysisdelta *nodeset) {
1120    changed := false
1121    for _x := range delta.AppendTo(a.deltaSpace) {
1122        typObj := nodeid(x)
1123        T := a.rtypeTaggedValue(typObj)
1124        tChanok := T.Underlying().(*types.Chan)
1125        if !ok || tChan.Dir() != types.SendRecv {
1126            continue // not a bidirectional channel type
1127        }
1128
1129        obj := a.nextNode()
1130        a.addNodes(tChan.Elem(), "reflect.MakeChan.value")
1131        a.endObject(objc.cgnnil)
1132
1133        // put its address in a new T-tagged object
1134        id := a.makeTagged(Tc.cgnnil)
1135        a.addLabel(id+1obj)
1136
1137        // flow the T-tagged object to the result
1138        if a.addLabel(c.resultid) {
1139            changed = true
1140        }
1141    }
1142    if changed {
1143        a.addWork(c.result)
1144    }
1145}
1146
1147func ext۰reflect۰MakeChan(a *analysiscgn *cgnode) {
1148    a.addConstraint(&reflectMakeChanConstraint{
1149        cgn:    cgn,
1150        typ:    a.funcParams(cgn.obj),
1151        resulta.funcResults(cgn.obj),
1152    })
1153}
1154
1155func ext۰reflect۰MakeFunc(a *analysiscgn *cgnode) {} // TODO(adonovan)
1156
1157// ---------- func MakeMap(Type) Value ----------
1158
1159// result = MakeMap(typ)
1160type reflectMakeMapConstraint struct {
1161    cgn    *cgnode
1162    typ    nodeid // (ptr)
1163    result nodeid // (indirect)
1164}
1165
1166func (c *reflectMakeMapConstraintptr() nodeid { return c.typ }
1167func (c *reflectMakeMapConstraintpresolve(h *hvn) {
1168    h.markIndirect(onodeid(c.result), "reflectMakeMap.result")
1169}
1170func (c *reflectMakeMapConstraintrenumber(mapping []nodeid) {
1171    c.typ = mapping[c.typ]
1172    c.result = mapping[c.result]
1173}
1174
1175func (c *reflectMakeMapConstraintString() string {
1176    return fmt.Sprintf("n%d = reflect.MakeMap(n%d)"c.resultc.typ)
1177}
1178
1179func (c *reflectMakeMapConstraintsolve(a *analysisdelta *nodeset) {
1180    changed := false
1181    for _x := range delta.AppendTo(a.deltaSpace) {
1182        typObj := nodeid(x)
1183        T := a.rtypeTaggedValue(typObj)
1184        tMapok := T.Underlying().(*types.Map)
1185        if !ok {
1186            continue // not a map type
1187        }
1188
1189        mapObj := a.nextNode()
1190        a.addNodes(tMap.Key(), "reflect.MakeMap.key")
1191        a.addNodes(tMap.Elem(), "reflect.MakeMap.value")
1192        a.endObject(mapObjc.cgnnil)
1193
1194        // put its address in a new T-tagged object
1195        id := a.makeTagged(Tc.cgnnil)
1196        a.addLabel(id+1mapObj)
1197
1198        // flow the T-tagged object to the result
1199        if a.addLabel(c.resultid) {
1200            changed = true
1201        }
1202    }
1203    if changed {
1204        a.addWork(c.result)
1205    }
1206}
1207
1208func ext۰reflect۰MakeMap(a *analysiscgn *cgnode) {
1209    a.addConstraint(&reflectMakeMapConstraint{
1210        cgn:    cgn,
1211        typ:    a.funcParams(cgn.obj),
1212        resulta.funcResults(cgn.obj),
1213    })
1214}
1215
1216// ---------- func MakeSlice(Type) Value ----------
1217
1218// result = MakeSlice(typ)
1219type reflectMakeSliceConstraint struct {
1220    cgn    *cgnode
1221    typ    nodeid // (ptr)
1222    result nodeid // (indirect)
1223}
1224
1225func (c *reflectMakeSliceConstraintptr() nodeid { return c.typ }
1226func (c *reflectMakeSliceConstraintpresolve(h *hvn) {
1227    h.markIndirect(onodeid(c.result), "reflectMakeSlice.result")
1228}
1229func (c *reflectMakeSliceConstraintrenumber(mapping []nodeid) {
1230    c.typ = mapping[c.typ]
1231    c.result = mapping[c.result]
1232}
1233
1234func (c *reflectMakeSliceConstraintString() string {
1235    return fmt.Sprintf("n%d = reflect.MakeSlice(n%d)"c.resultc.typ)
1236}
1237
1238func (c *reflectMakeSliceConstraintsolve(a *analysisdelta *nodeset) {
1239    changed := false
1240    for _x := range delta.AppendTo(a.deltaSpace) {
1241        typObj := nodeid(x)
1242        T := a.rtypeTaggedValue(typObj)
1243        if _ok := T.Underlying().(*types.Slice); !ok {
1244            continue // not a slice type
1245        }
1246
1247        obj := a.nextNode()
1248        a.addNodes(sliceToArray(T), "reflect.MakeSlice")
1249        a.endObject(objc.cgnnil)
1250
1251        // put its address in a new T-tagged object
1252        id := a.makeTagged(Tc.cgnnil)
1253        a.addLabel(id+1obj)
1254
1255        // flow the T-tagged object to the result
1256        if a.addLabel(c.resultid) {
1257            changed = true
1258        }
1259    }
1260    if changed {
1261        a.addWork(c.result)
1262    }
1263}
1264
1265func ext۰reflect۰MakeSlice(a *analysiscgn *cgnode) {
1266    a.addConstraint(&reflectMakeSliceConstraint{
1267        cgn:    cgn,
1268        typ:    a.funcParams(cgn.obj),
1269        resulta.funcResults(cgn.obj),
1270    })
1271}
1272
1273func ext۰reflect۰MapOf(a *analysiscgn *cgnode) {} // TODO(adonovan)
1274
1275// ---------- func New(Type) Value ----------
1276
1277// result = New(typ)
1278type reflectNewConstraint struct {
1279    cgn    *cgnode
1280    typ    nodeid // (ptr)
1281    result nodeid // (indirect)
1282}
1283
1284func (c *reflectNewConstraintptr() nodeid { return c.typ }
1285func (c *reflectNewConstraintpresolve(h *hvn) {
1286    h.markIndirect(onodeid(c.result), "reflectNew.result")
1287}
1288func (c *reflectNewConstraintrenumber(mapping []nodeid) {
1289    c.typ = mapping[c.typ]
1290    c.result = mapping[c.result]
1291}
1292
1293func (c *reflectNewConstraintString() string {
1294    return fmt.Sprintf("n%d = reflect.New(n%d)"c.resultc.typ)
1295}
1296
1297func (c *reflectNewConstraintsolve(a *analysisdelta *nodeset) {
1298    changed := false
1299    for _x := range delta.AppendTo(a.deltaSpace) {
1300        typObj := nodeid(x)
1301        T := a.rtypeTaggedValue(typObj)
1302
1303        // allocate new T object
1304        newObj := a.nextNode()
1305        a.addNodes(T"reflect.New")
1306        a.endObject(newObjc.cgnnil)
1307
1308        // put its address in a new *T-tagged object
1309        id := a.makeTagged(types.NewPointer(T), c.cgnnil)
1310        a.addLabel(id+1newObj)
1311
1312        // flow the pointer to the result
1313        if a.addLabel(c.resultid) {
1314            changed = true
1315        }
1316    }
1317    if changed {
1318        a.addWork(c.result)
1319    }
1320}
1321
1322func ext۰reflect۰New(a *analysiscgn *cgnode) {
1323    a.addConstraint(&reflectNewConstraint{
1324        cgn:    cgn,
1325        typ:    a.funcParams(cgn.obj),
1326        resulta.funcResults(cgn.obj),
1327    })
1328}
1329
1330func ext۰reflect۰NewAt(a *analysiscgn *cgnode) {
1331    ext۰reflect۰New(acgn)
1332
1333    // TODO(adonovan): also report dynamic calls to unsound intrinsics.
1334    if site := cgn.callersitesite != nil {
1335        a.warnf(site.pos(), "unsound: %s contains a reflect.NewAt() call"site.instr.Parent())
1336    }
1337}
1338
1339// ---------- func PtrTo(Type) Type ----------
1340
1341// result = PtrTo(t)
1342type reflectPtrToConstraint struct {
1343    cgn    *cgnode
1344    t      nodeid // (ptr)
1345    result nodeid // (indirect)
1346}
1347
1348func (c *reflectPtrToConstraintptr() nodeid { return c.t }
1349func (c *reflectPtrToConstraintpresolve(h *hvn) {
1350    h.markIndirect(onodeid(c.result), "reflectPtrTo.result")
1351}
1352func (c *reflectPtrToConstraintrenumber(mapping []nodeid) {
1353    c.t = mapping[c.t]
1354    c.result = mapping[c.result]
1355}
1356
1357func (c *reflectPtrToConstraintString() string {
1358    return fmt.Sprintf("n%d = reflect.PtrTo(n%d)"c.resultc.t)
1359}
1360
1361func (c *reflectPtrToConstraintsolve(a *analysisdelta *nodeset) {
1362    changed := false
1363    for _x := range delta.AppendTo(a.deltaSpace) {
1364        tObj := nodeid(x)
1365        T := a.rtypeTaggedValue(tObj)
1366
1367        if typeTooHigh(T) {
1368            continue
1369        }
1370
1371        if a.addLabel(c.resulta.makeRtype(types.NewPointer(T))) {
1372            changed = true
1373        }
1374    }
1375    if changed {
1376        a.addWork(c.result)
1377    }
1378}
1379
1380func ext۰reflect۰PtrTo(a *analysiscgn *cgnode) {
1381    a.addConstraint(&reflectPtrToConstraint{
1382        cgn:    cgn,
1383        t:      a.funcParams(cgn.obj),
1384        resulta.funcResults(cgn.obj),
1385    })
1386}
1387
1388func ext۰reflect۰Select(a *analysiscgn *cgnode) {} // TODO(adonovan)
1389
1390// ---------- func SliceOf(Type) Type ----------
1391
1392// result = SliceOf(t)
1393type reflectSliceOfConstraint struct {
1394    cgn    *cgnode
1395    t      nodeid // (ptr)
1396    result nodeid // (indirect)
1397}
1398
1399func (c *reflectSliceOfConstraintptr() nodeid { return c.t }
1400func (c *reflectSliceOfConstraintpresolve(h *hvn) {
1401    h.markIndirect(onodeid(c.result), "reflectSliceOf.result")
1402}
1403func (c *reflectSliceOfConstraintrenumber(mapping []nodeid) {
1404    c.t = mapping[c.t]
1405    c.result = mapping[c.result]
1406}
1407
1408func (c *reflectSliceOfConstraintString() string {
1409    return fmt.Sprintf("n%d = reflect.SliceOf(n%d)"c.resultc.t)
1410}
1411
1412func (c *reflectSliceOfConstraintsolve(a *analysisdelta *nodeset) {
1413    changed := false
1414    for _x := range delta.AppendTo(a.deltaSpace) {
1415        tObj := nodeid(x)
1416        T := a.rtypeTaggedValue(tObj)
1417
1418        if typeTooHigh(T) {
1419            continue
1420        }
1421
1422        if a.addLabel(c.resulta.makeRtype(types.NewSlice(T))) {
1423            changed = true
1424        }
1425    }
1426    if changed {
1427        a.addWork(c.result)
1428    }
1429}
1430
1431func ext۰reflect۰SliceOf(a *analysiscgn *cgnode) {
1432    a.addConstraint(&reflectSliceOfConstraint{
1433        cgn:    cgn,
1434        t:      a.funcParams(cgn.obj),
1435        resulta.funcResults(cgn.obj),
1436    })
1437}
1438
1439// ---------- func TypeOf(v Value) Type ----------
1440
1441// result = TypeOf(i)
1442type reflectTypeOfConstraint struct {
1443    cgn    *cgnode
1444    i      nodeid // (ptr)
1445    result nodeid // (indirect)
1446}
1447
1448func (c *reflectTypeOfConstraintptr() nodeid { return c.i }
1449func (c *reflectTypeOfConstraintpresolve(h *hvn) {
1450    h.markIndirect(onodeid(c.result), "reflectTypeOf.result")
1451}
1452func (c *reflectTypeOfConstraintrenumber(mapping []nodeid) {
1453    c.i = mapping[c.i]
1454    c.result = mapping[c.result]
1455}
1456
1457func (c *reflectTypeOfConstraintString() string {
1458    return fmt.Sprintf("n%d = reflect.TypeOf(n%d)"c.resultc.i)
1459}
1460
1461func (c *reflectTypeOfConstraintsolve(a *analysisdelta *nodeset) {
1462    changed := false
1463    for _x := range delta.AppendTo(a.deltaSpace) {
1464        iObj := nodeid(x)
1465        tDyn__ := a.taggedValue(iObj)
1466        if a.addLabel(c.resulta.makeRtype(tDyn)) {
1467            changed = true
1468        }
1469    }
1470    if changed {
1471        a.addWork(c.result)
1472    }
1473}
1474
1475func ext۰reflect۰TypeOf(a *analysiscgn *cgnode) {
1476    a.addConstraint(&reflectTypeOfConstraint{
1477        cgn:    cgn,
1478        i:      a.funcParams(cgn.obj),
1479        resulta.funcResults(cgn.obj),
1480    })
1481}
1482
1483// ---------- func ValueOf(interface{}) Value ----------
1484
1485func ext۰reflect۰ValueOf(a *analysiscgn *cgnode) {
1486    // TODO(adonovan): when we start creating indirect tagged
1487    // objects, we'll need to handle them specially here since
1488    // they must never appear in the PTS of an interface{}.
1489    a.copy(a.funcResults(cgn.obj), a.funcParams(cgn.obj), 1)
1490}
1491
1492// ---------- func Zero(Type) Value ----------
1493
1494// result = Zero(typ)
1495type reflectZeroConstraint struct {
1496    cgn    *cgnode
1497    typ    nodeid // (ptr)
1498    result nodeid // (indirect)
1499}
1500
1501func (c *reflectZeroConstraintptr() nodeid { return c.typ }
1502func (c *reflectZeroConstraintpresolve(h *hvn) {
1503    h.markIndirect(onodeid(c.result), "reflectZero.result")
1504}
1505func (c *reflectZeroConstraintrenumber(mapping []nodeid) {
1506    c.typ = mapping[c.typ]
1507    c.result = mapping[c.result]
1508}
1509
1510func (c *reflectZeroConstraintString() string {
1511    return fmt.Sprintf("n%d = reflect.Zero(n%d)"c.resultc.typ)
1512}
1513
1514func (c *reflectZeroConstraintsolve(a *analysisdelta *nodeset) {
1515    changed := false
1516    for _x := range delta.AppendTo(a.deltaSpace) {
1517        typObj := nodeid(x)
1518        T := a.rtypeTaggedValue(typObj)
1519
1520        // TODO(adonovan): if T is an interface type, we need
1521        // to create an indirect tagged object containing
1522        // new(T).  To avoid updates of such shared values,
1523        // we'll need another flag on indirect tagged objects
1524        // that marks whether they are addressable or
1525        // readonly, just like the reflect package does.
1526
1527        // memoize using a.reflectZeros[T]
1528        var id nodeid
1529        if z := a.reflectZeros.At(T); false && z != nil {
1530            id = z.(nodeid)
1531        } else {
1532            id = a.makeTagged(Tc.cgnnil)
1533            a.reflectZeros.Set(Tid)
1534        }
1535        if a.addLabel(c.resultid) {
1536            changed = true
1537        }
1538    }
1539    if changed {
1540        a.addWork(c.result)
1541    }
1542}
1543
1544func ext۰reflect۰Zero(a *analysiscgn *cgnode) {
1545    a.addConstraint(&reflectZeroConstraint{
1546        cgn:    cgn,
1547        typ:    a.funcParams(cgn.obj),
1548        resulta.funcResults(cgn.obj),
1549    })
1550}
1551
1552// -------------------- (*reflect.rtype) methods --------------------
1553
1554// ---------- func (*rtype) Elem() Type ----------
1555
1556// result = Elem(t)
1557type rtypeElemConstraint struct {
1558    cgn    *cgnode
1559    t      nodeid // (ptr)
1560    result nodeid // (indirect)
1561}
1562
1563func (c *rtypeElemConstraintptr() nodeid { return c.t }
1564func (c *rtypeElemConstraintpresolve(h *hvn) {
1565    h.markIndirect(onodeid(c.result), "rtypeElem.result")
1566}
1567func (c *rtypeElemConstraintrenumber(mapping []nodeid) {
1568    c.t = mapping[c.t]
1569    c.result = mapping[c.result]
1570}
1571
1572func (c *rtypeElemConstraintString() string {
1573    return fmt.Sprintf("n%d = (*reflect.rtype).Elem(n%d)"c.resultc.t)
1574}
1575
1576func (c *rtypeElemConstraintsolve(a *analysisdelta *nodeset) {
1577    // Implemented by *types.{Map,Chan,Array,Slice,Pointer}.
1578    type hasElem interface {
1579        Elem() types.Type
1580    }
1581    changed := false
1582    for _x := range delta.AppendTo(a.deltaSpace) {
1583        tObj := nodeid(x)
1584        T := a.nodes[tObj].obj.data.(types.Type)
1585        if tHasElemok := T.Underlying().(hasElem); ok {
1586            if a.addLabel(c.resulta.makeRtype(tHasElem.Elem())) {
1587                changed = true
1588            }
1589        }
1590    }
1591    if changed {
1592        a.addWork(c.result)
1593    }
1594}
1595
1596func ext۰reflect۰rtype۰Elem(a *analysiscgn *cgnode) {
1597    a.addConstraint(&rtypeElemConstraint{
1598        cgn:    cgn,
1599        t:      a.funcParams(cgn.obj),
1600        resulta.funcResults(cgn.obj),
1601    })
1602}
1603
1604// ---------- func (*rtype) Field(int) StructField ----------
1605// ---------- func (*rtype) FieldByName(string) (StructField, bool) ----------
1606
1607// result = FieldByName(t, name)
1608// result = Field(t, _)
1609type rtypeFieldByNameConstraint struct {
1610    cgn    *cgnode
1611    name   string // name of field; "" for unknown
1612    t      nodeid // (ptr)
1613    result nodeid // (indirect)
1614}
1615
1616func (c *rtypeFieldByNameConstraintptr() nodeid { return c.t }
1617func (c *rtypeFieldByNameConstraintpresolve(h *hvn) {
1618    h.markIndirect(onodeid(c.result+3), "rtypeFieldByName.result.Type")
1619}
1620func (c *rtypeFieldByNameConstraintrenumber(mapping []nodeid) {
1621    c.t = mapping[c.t]
1622    c.result = mapping[c.result]
1623}
1624
1625func (c *rtypeFieldByNameConstraintString() string {
1626    return fmt.Sprintf("n%d = (*reflect.rtype).FieldByName(n%d, %q)"c.resultc.tc.name)
1627}
1628
1629func (c *rtypeFieldByNameConstraintsolve(a *analysisdelta *nodeset) {
1630    // type StructField struct {
1631    // 0    __identity__
1632    // 1    Name      string
1633    // 2    PkgPath   string
1634    // 3    Type      Type
1635    // 4    Tag       StructTag
1636    // 5    Offset    uintptr
1637    // 6    Index     []int
1638    // 7    Anonymous bool
1639    // }
1640
1641    for _x := range delta.AppendTo(a.deltaSpace) {
1642        tObj := nodeid(x)
1643        T := a.nodes[tObj].obj.data.(types.Type)
1644        tStructok := T.Underlying().(*types.Struct)
1645        if !ok {
1646            continue // not a struct type
1647        }
1648
1649        n := tStruct.NumFields()
1650        for i := 0i < ni++ {
1651            f := tStruct.Field(i)
1652            if c.name == "" || c.name == f.Name() {
1653
1654                // a.offsetOf(Type) is 3.
1655                if id := c.result + 3a.addLabel(ida.makeRtype(f.Type())) {
1656                    a.addWork(id)
1657                }
1658                // TODO(adonovan): StructField.Index should be non-nil.
1659            }
1660        }
1661    }
1662}
1663
1664func ext۰reflect۰rtype۰FieldByName(a *analysiscgn *cgnode) {
1665    // If we have access to the callsite,
1666    // and the argument is a string constant,
1667    // return only that field.
1668    var name string
1669    if site := cgn.callersitesite != nil {
1670        if cok := site.instr.Common().Args[0].(*ssa.Const); ok {
1671            name = constant.StringVal(c.Value)
1672        }
1673    }
1674
1675    a.addConstraint(&rtypeFieldByNameConstraint{
1676        cgn:    cgn,
1677        name:   name,
1678        t:      a.funcParams(cgn.obj),
1679        resulta.funcResults(cgn.obj),
1680    })
1681}
1682
1683func ext۰reflect۰rtype۰Field(a *analysiscgn *cgnode) {
1684    // No-one ever calls Field with a constant argument,
1685    // so we don't specialize that case.
1686    a.addConstraint(&rtypeFieldByNameConstraint{
1687        cgn:    cgn,
1688        t:      a.funcParams(cgn.obj),
1689        resulta.funcResults(cgn.obj),
1690    })
1691}
1692
1693func ext۰reflect۰rtype۰FieldByIndex(a *analysiscgn *cgnode)    {} // TODO(adonovan)
1694func ext۰reflect۰rtype۰FieldByNameFunc(a *analysiscgn *cgnode) {} // TODO(adonovan)
1695
1696// ---------- func (*rtype) In/Out(i int) Type ----------
1697
1698// result = In/Out(t, i)
1699type rtypeInOutConstraint struct {
1700    cgn    *cgnode
1701    t      nodeid // (ptr)
1702    result nodeid // (indirect)
1703    out    bool
1704    i      int // -ve if not a constant
1705}
1706
1707func (c *rtypeInOutConstraintptr() nodeid { return c.t }
1708func (c *rtypeInOutConstraintpresolve(h *hvn) {
1709    h.markIndirect(onodeid(c.result), "rtypeInOut.result")
1710}
1711func (c *rtypeInOutConstraintrenumber(mapping []nodeid) {
1712    c.t = mapping[c.t]
1713    c.result = mapping[c.result]
1714}
1715
1716func (c *rtypeInOutConstraintString() string {
1717    return fmt.Sprintf("n%d = (*reflect.rtype).InOut(n%d, %d)"c.resultc.tc.i)
1718}
1719
1720func (c *rtypeInOutConstraintsolve(a *analysisdelta *nodeset) {
1721    changed := false
1722    for _x := range delta.AppendTo(a.deltaSpace) {
1723        tObj := nodeid(x)
1724        T := a.nodes[tObj].obj.data.(types.Type)
1725        sigok := T.Underlying().(*types.Signature)
1726        if !ok {
1727            continue // not a func type
1728        }
1729
1730        tuple := sig.Params()
1731        if c.out {
1732            tuple = sig.Results()
1733        }
1734        for in := 0tuple.Len(); i < ni++ {
1735            if c.i < 0 || c.i == i {
1736                if a.addLabel(c.resulta.makeRtype(tuple.At(i).Type())) {
1737                    changed = true
1738                }
1739            }
1740        }
1741    }
1742    if changed {
1743        a.addWork(c.result)
1744    }
1745}
1746
1747func ext۰reflect۰rtype۰InOut(a *analysiscgn *cgnodeout bool) {
1748    // If we have access to the callsite,
1749    // and the argument is an int constant,
1750    // return only that parameter.
1751    index := -1
1752    if site := cgn.callersitesite != nil {
1753        if cok := site.instr.Common().Args[0].(*ssa.Const); ok {
1754            index = int(c.Int64())
1755        }
1756    }
1757    a.addConstraint(&rtypeInOutConstraint{
1758        cgn:    cgn,
1759        t:      a.funcParams(cgn.obj),
1760        resulta.funcResults(cgn.obj),
1761        out:    out,
1762        i:      index,
1763    })
1764}
1765
1766func ext۰reflect۰rtype۰In(a *analysiscgn *cgnode) {
1767    ext۰reflect۰rtype۰InOut(acgnfalse)
1768}
1769
1770func ext۰reflect۰rtype۰Out(a *analysiscgn *cgnode) {
1771    ext۰reflect۰rtype۰InOut(acgntrue)
1772}
1773
1774// ---------- func (*rtype) Key() Type ----------
1775
1776// result = Key(t)
1777type rtypeKeyConstraint struct {
1778    cgn    *cgnode
1779    t      nodeid // (ptr)
1780    result nodeid // (indirect)
1781}
1782
1783func (c *rtypeKeyConstraintptr() nodeid { return c.t }
1784func (c *rtypeKeyConstraintpresolve(h *hvn) {
1785    h.markIndirect(onodeid(c.result), "rtypeKey.result")
1786}
1787func (c *rtypeKeyConstraintrenumber(mapping []nodeid) {
1788    c.t = mapping[c.t]
1789    c.result = mapping[c.result]
1790}
1791
1792func (c *rtypeKeyConstraintString() string {
1793    return fmt.Sprintf("n%d = (*reflect.rtype).Key(n%d)"c.resultc.t)
1794}
1795
1796func (c *rtypeKeyConstraintsolve(a *analysisdelta *nodeset) {
1797    changed := false
1798    for _x := range delta.AppendTo(a.deltaSpace) {
1799        tObj := nodeid(x)
1800        T := a.nodes[tObj].obj.data.(types.Type)
1801        if tMapok := T.Underlying().(*types.Map); ok {
1802            if a.addLabel(c.resulta.makeRtype(tMap.Key())) {
1803                changed = true
1804            }
1805        }
1806    }
1807    if changed {
1808        a.addWork(c.result)
1809    }
1810}
1811
1812func ext۰reflect۰rtype۰Key(a *analysiscgn *cgnode) {
1813    a.addConstraint(&rtypeKeyConstraint{
1814        cgn:    cgn,
1815        t:      a.funcParams(cgn.obj),
1816        resulta.funcResults(cgn.obj),
1817    })
1818}
1819
1820// ---------- func (*rtype) Method(int) (Method, bool) ----------
1821// ---------- func (*rtype) MethodByName(string) (Method, bool) ----------
1822
1823// result = MethodByName(t, name)
1824// result = Method(t, _)
1825type rtypeMethodByNameConstraint struct {
1826    cgn    *cgnode
1827    name   string // name of method; "" for unknown
1828    t      nodeid // (ptr)
1829    result nodeid // (indirect)
1830}
1831
1832func (c *rtypeMethodByNameConstraintptr() nodeid { return c.t }
1833func (c *rtypeMethodByNameConstraintpresolve(h *hvn) {
1834    h.markIndirect(onodeid(c.result+3), "rtypeMethodByName.result.Type")
1835    h.markIndirect(onodeid(c.result+4), "rtypeMethodByName.result.Func")
1836}
1837func (c *rtypeMethodByNameConstraintrenumber(mapping []nodeid) {
1838    c.t = mapping[c.t]
1839    c.result = mapping[c.result]
1840}
1841
1842func (c *rtypeMethodByNameConstraintString() string {
1843    return fmt.Sprintf("n%d = (*reflect.rtype).MethodByName(n%d, %q)"c.resultc.tc.name)
1844}
1845
1846// changeRecv returns sig with Recv prepended to Params().
1847func changeRecv(sig *types.Signature) *types.Signature {
1848    params := sig.Params()
1849    n := params.Len()
1850    p2 := make([]*types.Varn+1)
1851    p2[0] = sig.Recv()
1852    for i := 0i < ni++ {
1853        p2[i+1] = params.At(i)
1854    }
1855    return types.NewSignature(niltypes.NewTuple(p2...), sig.Results(), sig.Variadic())
1856}
1857
1858func (c *rtypeMethodByNameConstraintsolve(a *analysisdelta *nodeset) {
1859    for _x := range delta.AppendTo(a.deltaSpace) {
1860        tObj := nodeid(x)
1861        T := a.nodes[tObj].obj.data.(types.Type)
1862
1863        isIface := isInterface(T)
1864
1865        // We don't use Lookup(c.name) when c.name != "" to avoid
1866        // ambiguity: >1 unexported methods could match.
1867        mset := a.prog.MethodSets.MethodSet(T)
1868        for in := 0mset.Len(); i < ni++ {
1869            sel := mset.At(i)
1870            if c.name == "" || c.name == sel.Obj().Name() {
1871                // type Method struct {
1872                // 0     __identity__
1873                // 1    Name    string
1874                // 2    PkgPath string
1875                // 3    Type    Type
1876                // 4    Func    Value
1877                // 5    Index   int
1878                // }
1879
1880                var sig *types.Signature
1881                var fn *ssa.Function
1882                if isIface {
1883                    sig = sel.Type().(*types.Signature)
1884                } else {
1885                    fn = a.prog.MethodValue(sel)
1886                    // move receiver to params[0]
1887                    sig = changeRecv(fn.Signature)
1888                }
1889
1890                // a.offsetOf(Type) is 3.
1891                if id := c.result + 3a.addLabel(ida.makeRtype(sig)) {
1892                    a.addWork(id)
1893                }
1894                if fn != nil {
1895                    // a.offsetOf(Func) is 4.
1896                    if id := c.result + 4a.addLabel(ida.objectNode(nilfn)) {
1897                        a.addWork(id)
1898                    }
1899                }
1900            }
1901        }
1902    }
1903}
1904
1905func ext۰reflect۰rtype۰MethodByName(a *analysiscgn *cgnode) {
1906    // If we have access to the callsite,
1907    // and the argument is a string constant,
1908    // return only that method.
1909    var name string
1910    if site := cgn.callersitesite != nil {
1911        if cok := site.instr.Common().Args[0].(*ssa.Const); ok {
1912            name = constant.StringVal(c.Value)
1913        }
1914    }
1915
1916    a.addConstraint(&rtypeMethodByNameConstraint{
1917        cgn:    cgn,
1918        name:   name,
1919        t:      a.funcParams(cgn.obj),
1920        resulta.funcResults(cgn.obj),
1921    })
1922}
1923
1924func ext۰reflect۰rtype۰Method(a *analysiscgn *cgnode) {
1925    // No-one ever calls Method with a constant argument,
1926    // so we don't specialize that case.
1927    a.addConstraint(&rtypeMethodByNameConstraint{
1928        cgn:    cgn,
1929        t:      a.funcParams(cgn.obj),
1930        resulta.funcResults(cgn.obj),
1931    })
1932}
1933
1934// typeHeight returns the "height" of the type, which is roughly
1935// speaking the number of chan, map, pointer and slice type constructors
1936// at the root of T; these are the four type kinds that can be created
1937// via reflection.  Chan and map constructors are counted as double the
1938// height of slice and pointer constructors since they are less often
1939// deeply nested.
1940//
1941// The solver rules for type constructors must somehow bound the set of
1942// types they create to ensure termination of the algorithm in cases
1943// where the output of a type constructor flows to its input, e.g.
1944//
1945//    func f(t reflect.Type) {
1946//        f(reflect.PtrTo(t))
1947//    }
1948//
1949// It does this by limiting the type height to k, but this still leaves
1950// a potentially exponential (4^k) number of of types that may be
1951// enumerated in pathological cases.
1952func typeHeight(T types.Typeint {
1953    switch T := T.(type) {
1954    case *types.Chan:
1955        return 2 + typeHeight(T.Elem())
1956    case *types.Map:
1957        k := typeHeight(T.Key())
1958        v := typeHeight(T.Elem())
1959        if v > k {
1960            k = v // max(k, v)
1961        }
1962        return 2 + k
1963    case *types.Slice:
1964        return 1 + typeHeight(T.Elem())
1965    case *types.Pointer:
1966        return 1 + typeHeight(T.Elem())
1967    }
1968    return 0
1969}
1970
1971func typeTooHigh(T types.Typebool {
1972    return typeHeight(T) > 3
1973}
1974
MembersX
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.indirect
reflectMakeMapConstraint.cgn
reflectZeroConstraint.solve
ext۰reflect۰rtype۰Out.cgn
reflectCall.ret
rVElemConstraint
rVIndexConstraint.solve.RangeStmt_15877.BlockStmt.payload
ext۰reflect۰NewAt
reflectZeroConstraint.cgn
ext۰reflect۰Zero.cgn
rtypeFieldByNameConstraint.renumber
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.tObj
ext۰reflect۰Value۰MapIndex
rVSetMapIndexConstraint.solve.delta
ext۰reflect۰ChanOf.BlockStmt.BlockStmt.v
rtypeFieldByNameConstraint.result
ext۰reflect۰Value۰CallSlice
reflectMakeChanConstraint.presolve.c
ext۰reflect۰rtype۰FieldByName
rVSetMapIndexConstraint.solve
ext۰reflect۰ValueOf.cgn
rVMapIndexConstraint.solve.RangeStmt_18889.BlockStmt.m
rVSliceConstraint.presolve.c
rVMapKeysConstraint.solve.c
ext۰reflect۰Indirect
ext۰reflect۰MakeChan.cgn
reflectMakeMapConstraint.solve.c
reflectSliceOfConstraint.renumber.c
rtypeElemConstraint.renumber
rVElemConstraint.solve.RangeStmt_14058.BlockStmt.tDyn
rVElemConstraint.solve.RangeStmt_14058.BlockStmt.payload
rVMapIndexConstraint.renumber.mapping
rtypeInOutConstraint.solve.c
ext۰reflect۰Value۰SetMapIndex.a
reflectPtrToConstraint.renumber.mapping
rVElemConstraint.renumber.c
rVMapKeysConstraint.String
rVRecvConstraint.renumber.c
rtypeInOutConstraint.String
rVBytesConstraint.ptr
ext۰reflect۰TypeOf.cgn
ext۰reflect۰Value۰Convert
rVElemConstraint.solve.changed
rVMapIndexConstraint.solve.RangeStmt_18889.x
rVRecvConstraint.solve.a
rtypeElemConstraint.ptr.c
rtypeMethodByNameConstraint.solve
ext۰reflect۰Value۰SetPointer.a
reflectMakeSliceConstraint.renumber
rtypeKeyConstraint
rtypeKeyConstraint.renumber.c
rVBytesConstraint
rVIndexConstraint.presolve
rVSendConstraint.solve.RangeStmt_23428.BlockStmt.ch
rtypeElemConstraint.presolve.c
rtypeKeyConstraint.cgn
reflectMakeChanConstraint.cgn
ext۰reflect۰AppendSlice.a
reflectChanOfConstraint.solve.c
reflectNewConstraint.solve.delta
rVIndexConstraint.result
rVSetMapIndexConstraint.solve.RangeStmt_26120.BlockStmt.keysize
rVSliceConstraint.solve.a
rtypeElemConstraint.t
rtypeKeyConstraint.t
reflectIndirectConstraint.solve.a
rVSliceConstraint.solve.RangeStmt_27917.BlockStmt.payload
rtypeMethodByNameConstraint.solve.a
ext۰reflect۰ChanOf.a
reflectNewConstraint.cgn
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.n
rVElemConstraint.result
reflectChanOfConstraint.solve.delta
ext۰reflect۰New.cgn
reflectPtrToConstraint.ptr.c
reflectPtrToConstraint.solve.RangeStmt_39587.BlockStmt.T
rVSliceConstraint.v
rVSetBytesConstraint.ptr
rVSetMapIndexConstraint.solve.RangeStmt_26120.BlockStmt.indirect
reflectIndirectConstraint.solve.RangeStmt_31999.BlockStmt.res
ext۰reflect۰Value۰CallSlice.cgn
rVIndexConstraint
rVSendConstraint.v
ext۰reflect۰Value۰FieldByIndex
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.BlockStmt.sel
rVCallConstraint.solve
ext۰reflect۰Value۰Slice.cgn
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.n
ext۰reflect۰rtype۰MethodByName
reflectChanOfConstraint.solve.RangeStmt_30062.BlockStmt.tObj
reflectMakeMapConstraint.typ
ext۰reflect۰rtype۰FieldByNameFunc.a
rtypeInOutConstraint.solve.delta
rVBytesConstraint.presolve
rVRecvConstraint.presolve
reflectIndirectConstraint.ptr.c
ext۰reflect۰Select
rVRecvConstraint.String.c
ext۰reflect۰Value۰MethodByName
reflectMakeChanConstraint.solve.a
rtypeMethodByNameConstraint.ptr
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.results
reflectCallImpl.dotdotdot
rVElemConstraint.solve.a
rVMapKeysConstraint.renumber.mapping
rVRecvConstraint.ptr.c
typeTooHigh.T
ext۰reflect۰Value۰Index.a
rVSetBytesConstraint.cgn
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.i
reflectSliceOfConstraint.result
ext۰reflect۰ChanOf.site
reflectPtrToConstraint.solve.RangeStmt_39587.BlockStmt.tObj
rVMapIndexConstraint.cgn
reflectChanOfConstraint.String
rVRecvConstraint.solve.delta
rVSendConstraint.renumber.c
rVSetBytesConstraint.solve.RangeStmt_24820.x
rVElemConstraint.renumber.mapping
rVElemConstraint.String.c
reflectZeroConstraint.solve.a
reflectMakeMapConstraint.solve.delta
reflectMakeMapConstraint.solve.changed
ext۰reflect۰rtype۰InOut
rtypeMethodByNameConstraint.solve.delta
rVBytesConstraint.String
rVCallConstraint.solve.c
rVSendConstraint.solve.RangeStmt_23428.BlockStmt.tDyn
reflectSliceOfConstraint.ptr.c
ext۰reflect۰SliceOf.cgn
rtypeKeyConstraint.presolve.c
reflectMakeSliceConstraint.cgn
rVElemConstraint.presolve
rVMapIndexConstraint.solve.RangeStmt_18889.BlockStmt.vObj
reflectPtrToConstraint.renumber.c
rtypeKeyConstraint.presolve.h
ext۰reflect۰rtype۰Method
ext۰reflect۰Value۰MapKeys
rVSliceConstraint.solve.changed
ext۰reflect۰Value۰Send.cgn
rVSetMapIndexConstraint.solve.RangeStmt_26120.BlockStmt.keytmp
reflectIndirectConstraint.solve.RangeStmt_31999.x
reflectNewConstraint.presolve.c
rVIndexConstraint.solve.changed
ext۰reflect۰Value۰MapKeys.a
reflectChanOfConstraint.solve.a
reflectZeroConstraint.solve.RangeStmt_43376.BlockStmt.id
ext۰reflect۰Value۰Method
reflectMakeSliceConstraint.renumber.c
reflectNewConstraint.renumber.c
reflectCallImpl.a
ext۰reflect۰Value۰Field.cgn
ext۰reflect۰MakeMap.cgn
reflectMakeSliceConstraint.renumber.mapping
rtypeFieldByNameConstraint.ptr.c
rtypeKeyConstraint.solve.RangeStmt_50783.x
reflectIndirectConstraint.solve.changed
reflectMakeMapConstraint.renumber
reflectMakeSliceConstraint.solve.delta
rVBytesConstraint.ptr.c
ext۰reflect۰Value۰SetPointer.cgn
rVSetBytesConstraint.String
rtypeElemConstraint
rtypeElemConstraint.String.c
rVIndexConstraint.v
rVSendConstraint.ptr
rVBytesConstraint.renumber.mapping
reflectMakeChanConstraint.solve.RangeStmt_33395.BlockStmt.T
reflectNewConstraint.String
reflectIndirectConstraint.solve
reflectMakeChanConstraint.renumber.c
reflectMakeMapConstraint.String
rVCallConstraint.String
ext۰reflect۰NewAt.a
reflectPtrToConstraint.cgn
reflectZeroConstraint.presolve.h
rVCallConstraint.cgn
reflectCallImpl
rVInterfaceConstraint.String
rtypeFieldByNameConstraint.solve.RangeStmt_46718.BlockStmt.BlockStmt.f
reflectMakeMapConstraint.solve.RangeStmt_34967.BlockStmt.mapObj
reflectNewConstraint.solve.c
rVCallConstraint.ptr.c
rVCallConstraint.renumber
ext۰reflect۰Value۰SetBytes
reflectZeroConstraint.presolve.c
ext۰reflect۰Value۰Recv.a
rVSetMapIndexConstraint.ptr
rVMapIndexConstraint
rVSetBytesConstraint.renumber.mapping
ext۰reflect۰Value۰Bytes.a
rtypeFieldByNameConstraint.solve
ext۰reflect۰Value۰Call.a
rVMapIndexConstraint.solve.a
rVRecvConstraint.solve
rVSetBytesConstraint.x
rtypeFieldByNameConstraint.solve.RangeStmt_46718.BlockStmt.tObj
changeRecv.i
rtypeMethodByNameConstraint.renumber.c
ext۰reflect۰Value۰Set.a
rVSliceConstraint.renumber
rVBytesConstraint.solve.RangeStmt_8243.BlockStmt.slice
reflectMakeSliceConstraint.solve.RangeStmt_36483.BlockStmt.id
reflectPtrToConstraint.solve
ext۰reflect۰rtype۰Elem.a
ext۰reflect۰Value۰SetMapIndex.cgn
reflectChanOfConstraint.solve.RangeStmt_30062.BlockStmt.RangeStmt_30205.dir
rVElemConstraint.presolve.h
rVRecvConstraint.presolve.h
rVRecvConstraint.solve.RangeStmt_22141.BlockStmt.ch
reflectSliceOfConstraint.solve.c
rVBytesConstraint.solve.a
reflectNewConstraint.solve.RangeStmt_37959.BlockStmt.newObj
rtypeElemConstraint.renumber.c
rVIndexConstraint.presolve.c
rVIndexConstraint.solve.RangeStmt_15877.BlockStmt.res
rVMapKeysConstraint.result
ext۰reflect۰Value۰Recv
reflectPtrToConstraint.solve.c
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.i
reflectZeroConstraint.renumber.mapping
ext۰reflect۰Copy.cgn
reflectChanOfConstraint.solve.RangeStmt_30062.x
reflectMakeMapConstraint.solve.RangeStmt_34967.BlockStmt.T
ext۰reflect۰SliceOf.a
rtypeElemConstraint.result
ext۰reflect۰Value۰FieldByIndex.cgn
rVSendConstraint
rVSendConstraint.solve.RangeStmt_23428.x
reflectCallImpl.ret
rtypeInOutConstraint.solve.RangeStmt_48947.BlockStmt.i
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.isIface
reflectCallImpl.cgn
rVMapIndexConstraint.solve.delta
rtypeInOutConstraint.i
reflectZeroConstraint.result
rtypeKeyConstraint.solve.RangeStmt_50783.BlockStmt.tObj
rVMapIndexConstraint.result
ext۰reflect۰MapOf.cgn
reflectMakeSliceConstraint.solve
reflectNewConstraint.ptr.c
rtypeMethodByNameConstraint
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.BlockStmt.T
rVInterfaceConstraint.v
rVSetMapIndexConstraint.ptr.c
reflectMakeChanConstraint
rtypeFieldByNameConstraint.t
rtypeFieldByNameConstraint.solve.RangeStmt_46718.BlockStmt.n
ext۰reflect۰rtype۰Field.cgn
rVBytesConstraint.solve.changed
rVInterfaceConstraint.solve.RangeStmt_17537.BlockStmt.tDyn
ext۰reflect۰Value۰SetPointer
ext۰reflect۰rtype۰In.a
rVCallConstraint.String.c
rVInterfaceConstraint.solve
ext۰reflect۰Select.a
rVBytesConstraint.result
rVElemConstraint.cgn
reflectZeroConstraint.solve.changed
reflectMakeSliceConstraint.solve.RangeStmt_36483.BlockStmt.T
rtypeInOutConstraint.cgn
rVCallConstraint.presolve
rVMapKeysConstraint.solve
rVSetBytesConstraint.ptr.c
rVInterfaceConstraint.String.c
rVRecvConstraint.result
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.BlockStmt.BlockStmt.sig
rVSendConstraint.solve.RangeStmt_23428.BlockStmt.xtmp
rVSetBytesConstraint.String.c
rVBytesConstraint.String.c
reflectTypeOfConstraint.presolve.h
ext۰reflect۰rtype۰Elem
rtypeMethodByNameConstraint.solve.c
rtypeMethodByNameConstraint.solve.RangeStmt_52586.x
rVInterfaceConstraint.solve.changed
rVSliceConstraint.solve.c
reflectNewConstraint.solve.RangeStmt_37959.BlockStmt.T
rVIndexConstraint.solve.RangeStmt_15877.BlockStmt.vObj
rVRecvConstraint.solve.RangeStmt_22141.BlockStmt.indirect
reflectMakeChanConstraint.result
rtypeKeyConstraint.result
rtypeKeyConstraint.solve.delta
rVBytesConstraint.presolve.c
reflectChanOfConstraint.renumber.c
ext۰reflect۰ChanOf.dir
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.BlockStmt.BlockStmt.obj
reflectIndirectConstraint.solve.c
reflectPtrToConstraint.result
rtypeFieldByNameConstraint.presolve
reflectZeroConstraint.ptr.c
rVMapIndexConstraint.String.c
rVRecvConstraint.solve.RangeStmt_22141.BlockStmt.vObj
reflectPtrToConstraint.solve.a
reflectMakeMapConstraint
reflectTypeOfConstraint.renumber.mapping
ext۰reflect۰Value۰Addr
rVElemConstraint.presolve.c
rVRecvConstraint.presolve.c
reflectPtrToConstraint.String.c
reflectCallImpl.arg
ext۰reflect۰Value۰Elem.a
reflectMakeChanConstraint.solve.RangeStmt_33395.x
reflectSliceOfConstraint.String.c
ext۰reflect۰rtype۰FieldByIndex.cgn
rVSetBytesConstraint.solve
ext۰reflect۰AppendSlice.cgn
reflectMakeChanConstraint.String
init.RangeStmt_1384.fn
rVMapIndexConstraint.solve.RangeStmt_18889.BlockStmt.indirect
reflectZeroConstraint.solve.RangeStmt_43376.BlockStmt.z
rtypeInOutConstraint.solve.changed
reflectMakeChanConstraint.solve.c
reflectPtrToConstraint.presolve
reflectZeroConstraint.renumber
rtypeKeyConstraint.solve
ext۰reflect۰Value۰Call
rVIndexConstraint.String.c
reflectNewConstraint.solve
rVElemConstraint.renumber
rVMapKeysConstraint.renumber
reflectMakeSliceConstraint.ptr.c
rVBytesConstraint.solve
rVMapKeysConstraint.presolve.c
reflectMakeSliceConstraint.solve.c
reflectPtrToConstraint.presolve.c
rtypeFieldByNameConstraint.renumber.c
rVCallConstraint.solve.RangeStmt_9861.x
rVInterfaceConstraint.presolve.h
rVMapKeysConstraint.solve.RangeStmt_20323.BlockStmt.m
reflectMakeSliceConstraint.presolve
reflectNewConstraint.solve.RangeStmt_37959.x
rVInterfaceConstraint.presolve.c
ext۰reflect۰Value۰MapIndex.a
reflectMakeChanConstraint.String.c
rtypeKeyConstraint.solve.c
reflectMakeMapConstraint.ptr.c
reflectMakeSliceConstraint.String
rtypeInOutConstraint.presolve
rVRecvConstraint.renumber
rVSetBytesConstraint.solve.delta
reflectNewConstraint.String.c
ext۰reflect۰New
rVCallConstraint.renumber.mapping
rVInterfaceConstraint.renumber
rVMapKeysConstraint.solve.RangeStmt_20323.BlockStmt.kObj
reflectCall.dotdotdot
rVMapIndexConstraint.presolve.h
rtypeKeyConstraint.solve.a
rVBytesConstraint.solve.c
reflectCallImpl.site
rVCallConstraint.v
rVSetMapIndexConstraint.renumber.mapping
typeHeight
reflectMakeMapConstraint.renumber.mapping
ext۰reflect۰rtype۰FieldByName.name
ext۰reflect۰rtype۰Field.a
ext۰reflect۰Value۰FieldByName
ext۰reflect۰rtype۰InOut.out
rVRecvConstraint.solve.RangeStmt_22141.BlockStmt.tDyn
ext۰reflect۰TypeOf.a
rtypeElemConstraint.solve.RangeStmt_45125.BlockStmt.tObj
reflectSliceOfConstraint.solve.changed
reflectSliceOfConstraint.presolve
reflectTypeOfConstraint.result
rtypeFieldByNameConstraint.solve.RangeStmt_46718.BlockStmt.i
rVMapKeysConstraint.solve.delta
rVSliceConstraint.solve.delta
ext۰reflect۰Value۰SetBytes.a
reflectIndirectConstraint.String.c
rtypeInOutConstraint.renumber
ext۰reflect۰rtype۰In.cgn
rVBytesConstraint.solve.RangeStmt_8243.x
ext۰reflect۰Value۰MapIndex.cgn
rVSendConstraint.cgn
rVSendConstraint.renumber.mapping
rtypeFieldByNameConstraint.cgn
typeHeight.BlockStmt.k
rVElemConstraint.ptr
rVElemConstraint.solve.RangeStmt_14058.BlockStmt.BlockStmt.obj
rVInterfaceConstraint.solve.a
ext۰reflect۰Value۰FieldByNameFunc
rVInterfaceConstraint.solve.RangeStmt_17537.BlockStmt.payload
reflectMakeChanConstraint.presolve.h
rtypeInOutConstraint
reflectCallImpl.recv
ext۰reflect۰Value۰Call.cgn
ext۰reflect۰rtype۰MethodByName.cgn
typeHeight.T
rVMapKeysConstraint.renumber.c
rVSendConstraint.solve.a
reflectMakeMapConstraint.renumber.c
changeRecv.n
reflectCallImpl.argelts
rVSetBytesConstraint.solve.c
ext۰reflect۰NewAt.cgn
rVIndexConstraint.ptr
ext۰reflect۰MapOf
rtypeInOutConstraint.renumber.c
ext۰reflect۰rtype۰Out
rtypeMethodByNameConstraint.ptr.c
ext۰reflect۰Value۰MapKeys.obj
ext۰reflect۰Indirect.a
ext۰reflect۰MakeFunc
reflectPtrToConstraint.renumber
rVSetBytesConstraint.solve.RangeStmt_24820.BlockStmt.tDyn
rVSliceConstraint.solve.RangeStmt_27917.BlockStmt.vObj
reflectNewConstraint.renumber.mapping
rVCallConstraint.solve.changed
rVMapKeysConstraint.String.c
ext۰reflect۰NewAt.site
reflectTypeOfConstraint.cgn
rtypeMethodByNameConstraint.presolve.c
reflectZeroConstraint.String.c
rtypeElemConstraint.String
ext۰reflect۰rtype۰In
ext۰reflect۰rtype۰Out.a
ext۰reflect۰rtype۰Key.a
rVSetMapIndexConstraint.val
reflectChanOfConstraint.cgn
reflectChanOfConstraint.presolve.c
rtypeInOutConstraint.ptr
rtypeMethodByNameConstraint.presolve
reflectTypeOfConstraint.solve.RangeStmt_41948.BlockStmt._
ext۰reflect۰rtype۰FieldByName.cgn
reflectSliceOfConstraint.solve.delta
rVInterfaceConstraint
rVRecvConstraint.solve.changed
constant
ext۰reflect۰Value۰MethodByName.cgn
rVSetMapIndexConstraint.cgn
ext۰reflect۰AppendSlice
ext۰reflect۰MakeSlice.cgn
reflectPtrToConstraint
ext۰reflect۰Value۰FieldByName.a
rVIndexConstraint.String
rVInterfaceConstraint.ptr
reflectZeroConstraint.typ
rtypeElemConstraint.ptr
rVElemConstraint.solve.delta
rVSetMapIndexConstraint.String
rVSliceConstraint.renumber.mapping
init.RangeStmt_1384.name
ext۰reflect۰Value۰Bytes
rVCallConstraint.solve.delta
rtypeInOutConstraint.solve.RangeStmt_48947.BlockStmt.tObj
rtypeElemConstraint.solve.a
ext۰reflect۰Value۰Slice
reflectMakeSliceConstraint.solve.a
rtypeInOutConstraint.presolve.c
rVSendConstraint.presolve.c
rtypeKeyConstraint.ptr.c
rtypeElemConstraint.solve.delta
ext۰reflect۰rtype۰FieldByNameFunc.cgn
rVSetBytesConstraint.presolve.c
reflectIndirectConstraint.presolve.h
reflectZeroConstraint.presolve
ext۰reflect۰Zero.a
rtypeFieldByNameConstraint
rVElemConstraint.ptr.c
rVElemConstraint.solve.RangeStmt_14058.BlockStmt.indirect
ext۰reflect۰MakeChan.a
rVRecvConstraint.cgn
rVMapKeysConstraint
rtypeFieldByNameConstraint.renumber.mapping
rtypeMethodByNameConstraint.cgn
reflectZeroConstraint.solve.delta
rVSetBytesConstraint.solve.RangeStmt_24820.BlockStmt.vObj
rtypeElemConstraint.solve.RangeStmt_45125.x
ext۰reflect۰MapOf.a
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.mset
ext۰reflect۰Value۰FieldByNameFunc.cgn
reflectChanOfConstraint.renumber
ext۰reflect۰MakeFunc.cgn
reflectCall.recv
rVIndexConstraint.solve.RangeStmt_15877.BlockStmt.tDyn
changeRecv
reflectChanOfConstraint.dirs
rVMapKeysConstraint.solve.RangeStmt_20323.x
reflectIndirectConstraint
reflectNewConstraint.solve.RangeStmt_37959.BlockStmt.id
rVSendConstraint.renumber
rtypeFieldByNameConstraint.solve.delta
rtypeInOutConstraint.t
reflectSliceOfConstraint.presolve.c
reflectMakeChanConstraint.solve.delta
reflectMakeMapConstraint.String.c
reflectNewConstraint.solve.RangeStmt_37959.BlockStmt.typObj
ext۰reflect۰rtype۰MethodByName.site
ext۰reflect۰Value۰Send.a
rVSetBytesConstraint.renumber.c
rVSetMapIndexConstraint.String.c
rVElemConstraint.String
rVSliceConstraint.presolve.h
reflectMakeSliceConstraint.ptr
reflectMakeSliceConstraint.presolve.h
ext۰reflect۰rtype۰Key.cgn
rVSendConstraint.String
ext۰reflect۰Copy.a
reflectMakeSliceConstraint.presolve.c
reflectCall.site
ext۰reflect۰Append.a
rtypeFieldByNameConstraint.name
rVSetBytesConstraint
rtypeElemConstraint.solve
rVBytesConstraint.solve.RangeStmt_8243.BlockStmt.tDyn
ext۰reflect۰Value۰Method.cgn
rtypeInOutConstraint.solve.RangeStmt_48947.x
reflectTypeOfConstraint.presolve.c
ext۰reflect۰Value۰Send.params
rVIndexConstraint.ptr.c
rVMapIndexConstraint.ptr
rVSendConstraint.solve.RangeStmt_23428.BlockStmt.vObj
reflectChanOfConstraint.solve
reflectMakeMapConstraint.solve
rVBytesConstraint.solve.RangeStmt_8243.BlockStmt.vObj
rVInterfaceConstraint.result
ext۰reflect۰Value۰SetMapIndex.params
ext۰reflect۰PtrTo.cgn
rVSetMapIndexConstraint.presolve
ext۰reflect۰Append.cgn
reflectMakeMapConstraint.presolve.h
rtypeElemConstraint.solve.changed
rVInterfaceConstraint.solve.delta
rVMapIndexConstraint.v
ext۰reflect۰rtype۰Method.cgn
rVSliceConstraint.ptr.c
reflectMakeChanConstraint.renumber
reflectMakeMapConstraint.solve.a
reflectTypeOfConstraint.ptr.c
rtypeFieldByNameConstraint.solve.RangeStmt_46718.x
rtypeInOutConstraint.solve.RangeStmt_48947.BlockStmt.n
rtypeMethodByNameConstraint.name
rVSendConstraint.solve.c
reflectMakeSliceConstraint.typ
rVIndexConstraint.solve.delta
rVMapIndexConstraint.String
rVMapIndexConstraint.solve.RangeStmt_18889.BlockStmt.tDyn
rVSetMapIndexConstraint.v
rVRecvConstraint.solve.RangeStmt_22141.BlockStmt.tElem
rVSendConstraint.solve.RangeStmt_23428.BlockStmt.tElem
rVCallConstraint
reflectSliceOfConstraint.solve.a
reflectZeroConstraint
reflectZeroConstraint.solve.RangeStmt_43376.x
rtypeElemConstraint.renumber.mapping
rVSliceConstraint.result
ext۰reflect۰rtype۰Key
reflectChanOfConstraint.presolve
reflectIndirectConstraint.solve.delta
reflectSliceOfConstraint.solve.RangeStmt_40807.x
ext۰reflect۰rtype۰Method.a
rVElemConstraint.solve.RangeStmt_14058.x
rVIndexConstraint.solve.a
rVMapKeysConstraint.v
reflectTypeOfConstraint.String
rVMapIndexConstraint.solve.RangeStmt_18889.BlockStmt.obj
rtypeInOutConstraint.presolve.h
reflectChanOfConstraint.solve.RangeStmt_30062.BlockStmt.T
rtypeElemConstraint.presolve.h
rtypeKeyConstraint.renumber
rVElemConstraint.solve
rVSliceConstraint.solve.RangeStmt_27917.BlockStmt.tDyn
reflectTypeOfConstraint.solve.delta
rtypeMethodByNameConstraint.solve.RangeStmt_52586.BlockStmt.BlockStmt.BlockStmt.fn
ext۰reflect۰Value۰FieldByNameFunc.a
ext۰reflect۰Value۰SetMapIndex
reflectSliceOfConstraint.solve.RangeStmt_40807.BlockStmt.tObj
rVInterfaceConstraint.solve.RangeStmt_17537.BlockStmt.indirect
reflectPtrToConstraint.String
rVSliceConstraint
ext۰reflect۰MakeMap
reflectMakeChanConstraint.renumber.mapping
ext۰reflect۰MakeSlice.a
ext۰reflect۰rtype۰InOut.cgn
rVInterfaceConstraint.solve.c
ext۰reflect۰Value۰Set.cgn
rtypeMethodByNameConstraint.result
rVMapKeysConstraint.solve.RangeStmt_20323.BlockStmt.vObj
rVSendConstraint.solve.RangeStmt_23428.BlockStmt.indirect
ext۰reflect۰rtype۰Field
rVCallConstraint.result
rVMapIndexConstraint.solve.changed
reflectChanOfConstraint.presolve.h
reflectMakeChanConstraint.solve.RangeStmt_33395.BlockStmt.obj
reflectIndirectConstraint.renumber
reflectMakeSliceConstraint.result
reflectMakeSliceConstraint.solve.RangeStmt_36483.BlockStmt.obj
ext۰reflect۰Value۰Slice.a
ext۰reflect۰rtype۰FieldByIndex.a
rVMapKeysConstraint.solve.a
ext۰reflect۰rtype۰InOut.a
rVElemConstraint.solve.RangeStmt_14058.BlockStmt.vObj
ext۰reflect۰Value۰Field.a
rVSetBytesConstraint.solve.a
reflectTypeOfConstraint.renumber.c
rVSetMapIndexConstraint.solve.RangeStmt_26120.BlockStmt.tDyn
reflectIndirectConstraint.solve.RangeStmt_31999.BlockStmt.vObj
reflectMakeChanConstraint.ptr
reflectSliceOfConstraint.t
reflectTypeOfConstraint.i
rVIndexConstraint.presolve.h
ext۰reflect۰MakeFunc.a
rVRecvConstraint
reflectChanOfConstraint.String.c
reflectIndirectConstraint.renumber.mapping
rtypeFieldByNameConstraint.String.c
rVBytesConstraint.solve.delta
ext۰reflect۰Value۰Convert.a
ext۰reflect۰Value۰Interface
rVMapIndexConstraint.renumber.c
rVCallConstraint.ptr
ext۰reflect۰Value۰FieldByIndex.a
rVRecvConstraint.solve.RangeStmt_22141.x
ext۰reflect۰rtype۰FieldByIndex
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.tDyn
rVMapKeysConstraint.solve.RangeStmt_20323.BlockStmt.indirect
ext۰reflect۰Value۰Send
rVSliceConstraint.String.c
reflectMakeChanConstraint.solve.RangeStmt_33395.BlockStmt.typObj
rVInterfaceConstraint.presolve
rVBytesConstraint.renumber.c
reflectMakeSliceConstraint.String.c
rVBytesConstraint.solve.RangeStmt_8243.BlockStmt.indirect
rVCallConstraint.arg
rVInterfaceConstraint.renumber.mapping
rVMapIndexConstraint.presolve.c
ext۰reflect۰ChanOf.cgn
reflectMakeSliceConstraint.solve.changed
ext۰reflect۰Value۰Addr.cgn
ext۰reflect۰Value۰Interface.a
reflectChanOfConstraint.renumber.mapping
reflectMakeMapConstraint.presolve
rVSetMapIndexConstraint.renumber
reflectZeroConstraint.renumber.c
rtypeElemConstraint.presolve
rVRecvConstraint.v
ext۰reflect۰Value۰Index
reflectSliceOfConstraint
rVCallConstraint.presolve.c
reflectCall.a
reflectTypeOfConstraint.solve.RangeStmt_41948.BlockStmt.tDyn
rtypeElemConstraint.solve.hasElem
rVIndexConstraint.solve.RangeStmt_15877.x
rtypeKeyConstraint.renumber.mapping
rVSliceConstraint.ptr
ext۰reflect۰Indirect.cgn
reflectMakeChanConstraint.solve.RangeStmt_33395.BlockStmt.id
reflectNewConstraint.solve.changed
rtypeKeyConstraint.String.c
ext۰reflect۰Value۰CallSlice.a
ext۰reflect۰Value۰FieldByName.cgn
rVRecvConstraint.solve.RangeStmt_22141.BlockStmt.elemObj
ext۰reflect۰Value۰Method.a
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.params
ext۰reflect۰Value۰Interface.cgn
reflectIndirectConstraint.ptr
rtypeFieldByNameConstraint.solve.c
reflectPtrToConstraint.solve.RangeStmt_39587.x
ext۰reflect۰PtrTo.a
ext۰reflect۰TypeOf
ext۰reflect۰Value۰MapKeys.cgn
reflectMakeMapConstraint.result
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.fn
reflectIndirectConstraint.solve.RangeStmt_31999.BlockStmt._
rtypeMethodByNameConstraint.String
rVIndexConstraint.renumber.mapping
reflectPtrToConstraint.solve.changed
ext۰reflect۰Value۰SetBytes.cgn
reflectMakeMapConstraint.solve.RangeStmt_34967.BlockStmt.typObj
reflectTypeOfConstraint.solve.changed
rtypeInOutConstraint.renumber.mapping
rVSetMapIndexConstraint
rVSliceConstraint.String
reflectTypeOfConstraint.ptr
ext۰reflect۰Value۰Elem.cgn
rVIndexConstraint.solve.RangeStmt_15877.BlockStmt.indirect
rVSetMapIndexConstraint.presolve.c
rtypeFieldByNameConstraint.String
rtypeMethodByNameConstraint.t
rVCallConstraint.targets
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.vObj
ext۰reflect۰Value۰Elem
reflectPtrToConstraint.solve.delta
rVBytesConstraint.renumber
reflectCall
rVSetBytesConstraint.solve.RangeStmt_24820.BlockStmt.slice
ext۰reflect۰ValueOf
changeRecv.p2
ext۰reflect۰rtype۰MethodByName.a
rVMapKeysConstraint.ptr
rVSetMapIndexConstraint.solve.RangeStmt_26120.x
reflectChanOfConstraint.ptr
ext۰reflect۰MakeSlice
reflectSliceOfConstraint.renumber.mapping
reflectTypeOfConstraint.renumber
rVCallConstraint.solve.a
ext۰reflect۰Value۰Recv.cgn
rtypeInOutConstraint.result
rVRecvConstraint.String
reflectMakeMapConstraint.ptr
ext۰reflect۰Zero
reflectTypeOfConstraint
rVInterfaceConstraint.renumber.c
rVRecvConstraint.renumber.mapping
reflectChanOfConstraint.ptr.c
rVMapKeysConstraint.ptr.c
reflectMakeSliceConstraint.solve.RangeStmt_36483.BlockStmt.typObj
reflectTypeOfConstraint.solve.a
rtypeInOutConstraint.out
ext۰reflect۰Value۰MapKeys.T
reflectPtrToConstraint.ptr
reflectSliceOfConstraint.solve.RangeStmt_40807.BlockStmt.T
reflectSliceOfConstraint.solve
ext۰reflect۰rtype۰FieldByNameFunc
reflectChanOfConstraint.t
reflectMakeChanConstraint.presolve
reflectNewConstraint.renumber
ext۰reflect۰Append
ext۰reflect۰Copy
rtypeElemConstraint.solve.c
rtypeMethodByNameConstraint.String.c
rVCallConstraint.presolve.h
rVIndexConstraint.renumber.c
rVSetMapIndexConstraint.solve.a
ext۰reflect۰Value۰MethodByName.a
ext۰reflect۰ChanOf.params
reflectIndirectConstraint.String
rtypeInOutConstraint.solve.RangeStmt_48947.BlockStmt.tuple
ext۰reflect۰MakeMap.a
reflectMakeSliceConstraint.solve.RangeStmt_36483.x
reflectTypeOfConstraint.solve
rVIndexConstraint.renumber
ext۰reflect۰Value۰Index.cgn
ext۰reflect۰MakeChan
reflectMakeMapConstraint.solve.RangeStmt_34967.BlockStmt.id
rtypeInOutConstraint.solve.a
rVSendConstraint.ptr.c
ext۰reflect۰Value۰SetBytes.params
rVSetMapIndexConstraint.solve.RangeStmt_26120.BlockStmt.vObj
rVBytesConstraint.presolve.h
reflectChanOfConstraint.result
reflectMakeChanConstraint.solve.changed
ext۰reflect۰rtype۰MethodByName.name
rVElemConstraint.v
reflectIndirectConstraint.renumber.c
reflectMakeChanConstraint.ptr.c
reflectChanOfConstraint
reflectIndirectConstraint.result
rtypeInOutConstraint.String.c
ext۰reflect۰Value۰Field
reflectNewConstraint.presolve
rtypeElemConstraint.cgn
rVMapIndexConstraint.renumber
ext۰reflect۰Value۰Set
reflectIndirectConstraint.presolve
rVSliceConstraint.solve.RangeStmt_27917.BlockStmt.res
reflectPtrToConstraint.t
reflectSliceOfConstraint.ptr
reflectZeroConstraint.solve.c
rtypeInOutConstraint.solve
rVCallConstraint.renumber.c
rtypeKeyConstraint.solve.changed
ext۰reflect۰SliceOf
rVInterfaceConstraint.ptr.c
rVMapKeysConstraint.presolve
rVSendConstraint.x
rVMapKeysConstraint.solve.changed
rtypeFieldByNameConstraint.solve.a
rVIndexConstraint.cgn
rVMapIndexConstraint.solve.c
rtypeFieldByNameConstraint.presolve.c
rVBytesConstraint.v
rVIndexConstraint.solve
rVSetBytesConstraint.v
rVSetMapIndexConstraint.key
reflectMakeMapConstraint.presolve.c
reflectNewConstraint.ptr
reflectSliceOfConstraint.cgn
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.tResults
rVMapKeysConstraint.solve.RangeStmt_20323.BlockStmt.tDyn
reflectIndirectConstraint.solve.RangeStmt_31999.BlockStmt.tDyn
rtypeKeyConstraint.String
changeRecv.sig
ext۰reflect۰ValueOf.a
reflectZeroConstraint.solve.RangeStmt_43376.BlockStmt.typObj
rtypeKeyConstraint.ptr
rVSliceConstraint.solve
reflectNewConstraint.result
reflectTypeOfConstraint.presolve
rtypeMethodByNameConstraint.renumber
rVSendConstraint.solve.delta
rVSetMapIndexConstraint.solve.RangeStmt_26120.BlockStmt.valtmp
reflectSliceOfConstraint.String
rVSliceConstraint.solve.RangeStmt_27917.x
changeRecv.params
ext۰reflect۰Value۰Convert.cgn
rVElemConstraint.solve.c
rVMapIndexConstraint.presolve
reflectTypeOfConstraint.solve.c
ext۰reflect۰Value۰Bytes.cgn
rVSetMapIndexConstraint.renumber.c
reflectMakeMapConstraint.solve.RangeStmt_34967.x
rVSliceConstraint.renumber.c
ext۰reflect۰Value۰Addr.a
rVMapIndexConstraint.ptr.c
reflectZeroConstraint.solve.RangeStmt_43376.BlockStmt.T
reflectZeroConstraint.String
rVMapKeysConstraint.cgn
rVSetMapIndexConstraint.solve.c
reflectIndirectConstraint.presolve.c
rtypeMethodByNameConstraint.presolve.h
typeHeight.BlockStmt.v
rVSliceConstraint.cgn
rVSliceConstraint.presolve
reflectNewConstraint.solve.a
rVSendConstraint.String.c
reflectIndirectConstraint.v
reflectSliceOfConstraint.presolve.h
rtypeMethodByNameConstraint.renumber.mapping
rVMapIndexConstraint.solve
ext۰reflect۰ChanOf
rVSetBytesConstraint.solve.RangeStmt_24820.BlockStmt.indirect
reflectNewConstraint
ext۰reflect۰rtype۰FieldByName.site
rVCallConstraint.dotdotdot
rVSendConstraint.presolve
rVSetBytesConstraint.presolve
reflectMakeSliceConstraint
rVInterfaceConstraint.solve.RangeStmt_17537.x
reflectSliceOfConstraint.renumber
rVCallConstraint.solve.RangeStmt_9861.BlockStmt.tParams
reflectMakeChanConstraint.typ
ext۰reflect۰Select.cgn
reflectZeroConstraint.ptr
ext۰reflect۰rtype۰Elem.cgn
typeTooHigh
rVMapKeysConstraint.presolve.h
rVSetMapIndexConstraint.solve.RangeStmt_26120.BlockStmt.m
reflectMakeChanConstraint.solve
ext۰reflect۰PtrTo
reflectTypeOfConstraint.solve.RangeStmt_41948.BlockStmt.iObj
rVSliceConstraint.solve.RangeStmt_27917.BlockStmt.indirect
reflectIndirectConstraint.cgn
ext۰reflect۰New.a
rVInterfaceConstraint.solve.RangeStmt_17537.BlockStmt.vObj
reflectNewConstraint.typ
reflectTypeOfConstraint.solve.RangeStmt_41948.x
rtypeFieldByNameConstraint.ptr
rVSetBytesConstraint.renumber
rtypeFieldByNameConstraint.presolve.h
reflectCall.cgn
rVRecvConstraint.ptr
reflectPtrToConstraint.presolve.h
reflectTypeOfConstraint.String.c
reflectChanOfConstraint.solve.changed
rVIndexConstraint.solve.c
rVRecvConstraint.solve.c
ext۰reflect۰rtype۰FieldByName.a
rtypeInOutConstraint.ptr.c
ext۰reflect۰rtype۰InOut.site
rtypeKeyConstraint.presolve
rVSendConstraint.solve
reflectNewConstraint.presolve.h
Members
X