Beispiel #1
0
// makeConstant creates the value node and object node (if needed) for
// constant c, and returns the value node.
// An object node is created only for []byte or []rune constants.
// The value node points to the object node, iff present.
//
func (a *analysis) makeConstant(l *ssa.Const) nodeid {
	id := a.addNodes(l.Type(), "const")
	if !l.IsNil() {
		// []byte or []rune?
		if t, ok := l.Type().Underlying().(*types.Slice); ok {
			// Treat []T like *[1]T, 'make []T' like new([1]T).
			obj := a.nextNode()
			a.addNodes(sliceToArray(t), "array in slice constant")
			a.endObject(obj, nil, l)

			a.addressOf(id, obj)
		}
	}
	return id
}
Beispiel #2
0
// constValue returns the value of the constant with the
// dynamic type tag appropriate for c.Type().
func constValue(c *ssa.Const) value {
	if c.IsNil() {
		return zero(c.Type()) // typed nil
	}

	// By destination type:
	switch t := c.Type().Underlying().(type) {
	case *types.Basic:
		// TODO(adonovan): eliminate untyped constants from SSA form.
		switch t.Kind() {
		case types.Bool, types.UntypedBool:
			return exact.BoolVal(c.Value)
		case types.Int, types.UntypedInt:
			// Assume sizeof(int) is same on host and target.
			return int(c.Int64())
		case types.Int8:
			return int8(c.Int64())
		case types.Int16:
			return int16(c.Int64())
		case types.Int32, types.UntypedRune:
			return int32(c.Int64())
		case types.Int64:
			return c.Int64()
		case types.Uint:
			// Assume sizeof(uint) is same on host and target.
			return uint(c.Uint64())
		case types.Uint8:
			return uint8(c.Uint64())
		case types.Uint16:
			return uint16(c.Uint64())
		case types.Uint32:
			return uint32(c.Uint64())
		case types.Uint64:
			return c.Uint64()
		case types.Uintptr:
			// Assume sizeof(uintptr) is same on host and target.
			return uintptr(c.Uint64())
		case types.Float32:
			return float32(c.Float64())
		case types.Float64, types.UntypedFloat:
			return c.Float64()
		case types.Complex64:
			return complex64(c.Complex128())
		case types.Complex128, types.UntypedComplex:
			return c.Complex128()
		case types.String, types.UntypedString:
			if c.Value.Kind() == exact.String {
				return exact.StringVal(c.Value)
			}
			return string(rune(c.Int64()))
		case types.UnsafePointer:
			panic("unsafe.Pointer constant") // not possible
		case types.UntypedNil:
			// nil was handled above.
		}

	case *types.Slice:
		switch et := t.Elem().Underlying().(type) {
		case *types.Basic:
			switch et.Kind() {
			case types.Byte: // string -> []byte
				var v []value
				for _, b := range []byte(exact.StringVal(c.Value)) {
					v = append(v, b)
				}
				return v
			case types.Rune: // string -> []rune
				var v []value
				for _, r := range []rune(exact.StringVal(c.Value)) {
					v = append(v, r)
				}
				return v
			}
		}
	}

	panic(fmt.Sprintf("constValue: Value.(type)=%T Type()=%s", c.Value, c.Type()))
}