// visitAlloc is for variable allocation (usually by 'new') // Everything allocated here are pointers func visitAlloc(inst *ssa.Alloc, fr *frame) { locn := loc(fr, inst.Pos()) allocType := inst.Type().(*types.Pointer).Elem() if allocType == nil { panic("Alloc: Cannot Alloc for non-pointer type") } var val ssa.Value = inst switch t := allocType.Underlying().(type) { case *types.Array: vd := utils.NewDef(val) fr.locals[val] = vd if inst.Heap { fr.env.arrays[vd] = make(Elems) fmt.Fprintf(os.Stderr, " %s = Alloc (array@heap) of type %s (%d elems) at %s\n", cyan(reg(inst)), inst.Type().String(), t.Len(), locn) } else { fr.arrays[vd] = make(Elems) fmt.Fprintf(os.Stderr, " %s = Alloc (array@local) of type %s (%d elems) at %s\n", cyan(reg(inst)), inst.Type().String(), t.Len(), locn) } case *types.Chan: // VD will be created in MakeChan so no need to allocate here. fmt.Fprintf(os.Stderr, " %s = Alloc (chan) of type %s at %s\n", cyan(reg(inst)), inst.Type().String(), locn) case *types.Struct: vd := utils.NewDef(val) fr.locals[val] = vd if inst.Heap { fr.env.structs[vd] = make(Fields, t.NumFields()) fmt.Fprintf(os.Stderr, " %s = Alloc (struct@heap) of type %s (%d fields) at %s\n", cyan(reg(inst)), inst.Type().String(), t.NumFields(), locn) } else { fr.structs[vd] = make(Fields, t.NumFields()) fmt.Fprintf(os.Stderr, " %s = Alloc (struct@local) of type %s (%d fields) at %s\n", cyan(reg(inst)), inst.Type().String(), t.NumFields(), locn) } default: fmt.Fprintf(os.Stderr, " # %s = "+red("Alloc %s")+" of type %s\n", inst.Name(), inst.String(), t.String()) } }