case TMAP: // implemented as pointer
w = int64(Widthptr)
- checkwidth(t.Val())
+ checkwidth(t.Elem())
checkwidth(t.Key())
case TFORW: // should have been filled in
// perfect. Worst case, we might miss opportunities to inline
// some function calls in downstream packages.
switch t.Etype {
- case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN:
+ case TPTR32, TPTR64, TARRAY, TSLICE, TCHAN, TMAP:
p.markType(t.Elem())
- case TMAP:
- p.markType(t.Val())
-
case TSTRUCT:
for _, f := range t.FieldSlice() {
if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
case TMAP:
p.tag(mapTag)
p.typ(t.Key())
- p.typ(t.Val())
+ p.typ(t.Elem())
case TCHAN:
p.tag(chanTag)
t = p.newtyp(TMAP)
mt := t.MapType()
mt.Key = p.typ()
- mt.Val = p.typ()
+ mt.Elem = p.typ()
case chanTag:
t = p.newtyp(TCHAN)
return "chan " + tmodeString(t.Elem(), mode, depth)
case TMAP:
- return "map[" + tmodeString(t.Key(), mode, depth) + "]" + tmodeString(t.Val(), mode, depth)
+ return "map[" + tmodeString(t.Key(), mode, depth) + "]" + tmodeString(t.Elem(), mode, depth)
case TINTER:
if t.IsEmptyInterface() {
mt := m.MapType()
// Format the bucket struct for map[x]y as map.bucket[x]y.
// This avoids a recursive print that generates very long names.
- if mt.Bucket == t {
- return "map.bucket[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth)
- }
-
- if mt.Hmap == t {
- return "map.hdr[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth)
- }
-
- if mt.Hiter == t {
- return "map.iter[" + tmodeString(m.Key(), mode, depth) + "]" + tmodeString(m.Val(), mode, depth)
+ var subtype string
+ switch t {
+ case mt.Bucket:
+ subtype = "bucket"
+ case mt.Hmap:
+ subtype = "hdr"
+ case mt.Hiter:
+ subtype = "iter"
+ default:
+ Fatalf("unknown internal map type")
}
-
- Fatalf("unknown internal map type")
+ return fmt.Sprintf("map.%s[%s]%s", subtype, tmodeString(m.Key(), mode, depth), tmodeString(m.Elem(), mode, depth))
}
buf := make([]byte, 0, 64)
case TMAP:
w.startType(mapType)
w.typ(t.Key())
- w.typ(t.Val())
+ w.typ(t.Elem())
case TFUNC:
w.startType(signatureType)
case TMAP:
t1 = t.Key()
- t2 = t.Val()
+ t2 = t.Elem()
case TCHAN:
if !t.ChanDir().CanRecv() {
fn := syslook("mapiterinit")
- fn = substArgTypes(fn, t.Key(), t.Val(), th)
+ fn = substArgTypes(fn, t.Key(), t.Elem(), th)
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, nod(OADDR, hit, nil)))
n.Left = nod(ONE, nodSym(ODOT, hit, keysym), nodnil())
bucket := types.New(TSTRUCT)
keytype := t.Key()
- valtype := t.Val()
+ valtype := t.Elem()
dowidth(keytype)
dowidth(valtype)
if keytype.Width > MAXKEYSIZE {
if t.Key().Width > MAXKEYSIZE && !keytype.IsPtr() {
Fatalf("key indirect incorrect for %v", t)
}
- if t.Val().Width > MAXVALSIZE && !valtype.IsPtr() {
+ if t.Elem().Width > MAXVALSIZE && !valtype.IsPtr() {
Fatalf("value indirect incorrect for %v", t)
}
if keytype.Width%int64(keytype.Align) != 0 {
// }
// must match ../../../../runtime/map.go:hiter.
fields := []*types.Field{
- makefield("key", types.NewPtr(t.Key())), // Used in range.go for TMAP.
- makefield("val", types.NewPtr(t.Val())), // Used in range.go for TMAP.
+ makefield("key", types.NewPtr(t.Key())), // Used in range.go for TMAP.
+ makefield("val", types.NewPtr(t.Elem())), // Used in range.go for TMAP.
makefield("t", types.Types[TUNSAFEPTR]),
makefield("h", types.NewPtr(hmap)),
makefield("buckets", types.NewPtr(bmap)),
// ../../../../runtime/type.go:/mapType
case TMAP:
s1 := dtypesym(t.Key())
- s2 := dtypesym(t.Val())
+ s2 := dtypesym(t.Elem())
s3 := dtypesym(bmap(t))
s4 := dtypesym(hmap(t))
ot = dcommontype(lsym, t)
ot = duint8(lsym, ot, 0) // not indirect
}
- if t.Val().Width > MAXVALSIZE {
+ if t.Elem().Width > MAXVALSIZE {
ot = duint8(lsym, ot, uint8(Widthptr))
ot = duint8(lsym, ot, 1) // indirect
} else {
- ot = duint8(lsym, ot, uint8(t.Val().Width))
+ ot = duint8(lsym, ot, uint8(t.Elem().Width))
ot = duint8(lsym, ot, 0) // not indirect
}
// build types [count]Tindex and [count]Tvalue
tk := types.NewArray(n.Type.Key(), int64(len(stat)))
- tv := types.NewArray(n.Type.Val(), int64(len(stat)))
+ tv := types.NewArray(n.Type.Elem(), int64(len(stat)))
// TODO(josharian): suppress alg generation for these types?
dowidth(tk)
// Use temporaries so that mapassign1 can have addressable key, val.
// TODO(josharian): avoid map key temporaries for mapfast_* assignments with literal keys.
key := temp(m.Type.Key())
- val := temp(m.Type.Val())
+ val := temp(m.Type.Elem())
for _, r := range dyn {
index, value := r.Left, r.Right
if !eqtype1(t1.Key(), t2.Key(), cmpTags, assumedEqual) {
return false
}
- return eqtype1(t1.Val(), t2.Val(), cmpTags, assumedEqual)
}
return eqtype1(t1.Elem(), t2.Elem(), cmpTags, assumedEqual)
if n.Right.Type != nil {
n.Right = assignconv(n.Right, t.Key(), "map index")
}
- n.Type = t.Val()
+ n.Type = t.Elem()
n.Op = OINDEXMAP
n.ResetAux()
}
}
r = l.Right
- pushtype(r, t.Val())
+ pushtype(r, t.Elem())
r = typecheck(r, Erv)
- r = defaultlit(r, t.Val())
- l.Right = assignconv(r, t.Val(), "map value")
+ r = defaultlit(r, t.Elem())
+ l.Right = assignconv(r, t.Elem(), "map value")
}
n.Op = OMAPLIT
// a = *var
a := n.List.First()
- if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
+ if w := t.Elem().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
fn := mapfn(mapaccess2[fast], t)
r = mkcall1(fn, fn.Type.Results(), init, typename(t), r.Left, key)
} else {
// don't generate a = *var if a is _
if !a.isBlank() {
- var_ := temp(types.NewPtr(t.Val()))
+ var_ := temp(types.NewPtr(t.Elem()))
var_.SetTypecheck(1)
var_.SetNonNil(true) // mapaccess always returns a non-nil pointer
n.List.SetFirst(var_)
key = nod(OADDR, key, nil)
}
- if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
- n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Val()), init, typename(t), map_, key)
+ if w := t.Elem().Width; w <= 1024 { // 1024 must match ../../../../runtime/map.go:maxZero
+ n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Elem()), init, typename(t), map_, key)
} else {
z := zeroaddr(w)
- n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Val()), init, typename(t), map_, key, z)
+ n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Elem()), init, typename(t), map_, key, z)
}
}
- n.Type = types.NewPtr(t.Val())
+ n.Type = types.NewPtr(t.Elem())
n.SetNonNil(true) // mapaccess1* and mapassign always return non-nil pointers.
n = nod(OIND, n, nil)
- n.Type = t.Val()
+ n.Type = t.Elem()
n.SetTypecheck(1)
case ORECV:
// Call runtime.makehmap to allocate an
// hmap on the heap and initialize hmap's hash0 field.
fn := syslook("makemap_small")
- fn = substArgTypes(fn, t.Key(), t.Val())
+ fn = substArgTypes(fn, t.Key(), t.Elem())
n = mkcall1(fn, n.Type, init)
}
} else {
}
fn := syslook(fnname)
- fn = substArgTypes(fn, hmapType, t.Key(), t.Val())
+ fn = substArgTypes(fn, hmapType, t.Key(), t.Elem())
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(hint, argtype), h)
}
Fatalf("mapfn %v", t)
}
fn := syslook(name)
- fn = substArgTypes(fn, t.Key(), t.Val(), t.Key(), t.Val())
+ fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key(), t.Elem())
return fn
}
Fatalf("mapfn %v", t)
}
fn := syslook(name)
- fn = substArgTypes(fn, t.Key(), t.Val(), t.Key())
+ fn = substArgTypes(fn, t.Key(), t.Elem(), t.Key())
return fn
}
func mapfast(t *types.Type) int {
// Check ../../runtime/map.go:maxValueSize before changing.
- if t.Val().Width > 128 {
+ if t.Elem().Width > 128 {
return mapslow
}
switch algtype(t.Key()) {
// Map contains Type fields specific to maps.
type Map struct {
- Key *Type // Key type
- Val *Type // Val (elem) type
+ Key *Type // Key type
+ Elem *Type // Val (elem) type
Bucket *Type // internal struct type representing a hash bucket
Hmap *Type // internal struct type representing the Hmap (map header object)
t := New(TMAP)
mt := t.MapType()
mt.Key = k
- mt.Val = v
+ mt.Elem = v
return t
}
case TMAP:
key := SubstAny(t.Key(), types)
- val := SubstAny(t.Val(), types)
- if key != t.Key() || val != t.Val() {
+ elem := SubstAny(t.Elem(), types)
+ if key != t.Key() || elem != t.Elem() {
t = t.copy()
t.Extra.(*Map).Key = key
- t.Extra.(*Map).Val = val
+ t.Extra.(*Map).Elem = elem
}
case TFUNC:
return t.Extra.(*Map).Key
}
-// Val returns the value type of map type t.
-func (t *Type) Val() *Type {
- t.wantEtype(TMAP)
- return t.Extra.(*Map).Val
-}
-
// Elem returns the type of elements of t.
-// Usable with pointers, channels, arrays, and slices.
+// Usable with pointers, channels, arrays, slices, and maps.
func (t *Type) Elem() *Type {
switch t.Etype {
case TPTR32, TPTR64:
return t.Extra.(Slice).Elem
case TCHAN:
return t.Extra.(*Chan).Elem
+ case TMAP:
+ return t.Extra.(*Map).Elem
}
Fatalf("Type.Elem %s", t.Etype)
return nil
if c := t.Key().cmp(x.Key()); c != CMPeq {
return c
}
- return t.Val().cmp(x.Val())
+ return t.Elem().cmp(x.Elem())
case TPTR32, TPTR64, TSLICE:
// No special cases for these, they are handled