// If this PointsToSet came from a Pointer of interface kind // or a reflect.Value, DynamicTypes returns the set of dynamic // types that it may contain. (For an interface, they will // always be concrete types.) // // The result is a mapping whose keys are the dynamic types to which // it may point. For each pointer-like key type, the corresponding // map value is the PointsToSet for pointers of that type. // // The result is empty unless CanHaveDynamicTypes(T). // func (s PointsToSet) DynamicTypes() *typeutil.Map { var tmap typeutil.Map tmap.SetHasher(s.a.hasher) for ifaceObjId := range s.pts { if !s.a.isTaggedObject(ifaceObjId) { continue // !CanHaveDynamicTypes(tDyn) } tDyn, v, indirect := s.a.taggedValue(ifaceObjId) if indirect { panic("indirect tagged object") // implement later } pts, ok := tmap.At(tDyn).(PointsToSet) if !ok { pts = PointsToSet{s.a, make(nodeset)} tmap.Set(tDyn, pts) } pts.pts.addAll(s.a.nodes[v].pts) } return &tmap }
// If this PointsToSet came from a Pointer of interface kind // or a reflect.Value, DynamicTypes returns the set of dynamic // types that it may contain. (For an interface, they will // always be concrete types.) // // The result is a mapping whose keys are the dynamic types to which // it may point. For each pointer-like key type, the corresponding // map value is the PointsToSet for pointers of that type. // // The result is empty unless CanHaveDynamicTypes(T). // func (s PointsToSet) DynamicTypes() *typeutil.Map { var tmap typeutil.Map tmap.SetHasher(s.a.hasher) if s.pts != nil { var space [50]int for _, x := range s.pts.AppendTo(space[:0]) { ifaceObjId := nodeid(x) if !s.a.isTaggedObject(ifaceObjId) { continue // !CanHaveDynamicTypes(tDyn) } tDyn, v, indirect := s.a.taggedValue(ifaceObjId) if indirect { panic("indirect tagged object") // implement later } pts, ok := tmap.At(tDyn).(PointsToSet) if !ok { pts = PointsToSet{s.a, new(nodeset)} tmap.Set(tDyn, pts) } pts.pts.addAll(&s.a.nodes[v].solve.pts) } } return &tmap }