1
2
3
4
5 package noder
6
7 import (
8 "go/constant"
9
10 "cmd/compile/internal/ir"
11 "cmd/compile/internal/syntax"
12 "cmd/compile/internal/typecheck"
13 "cmd/compile/internal/types"
14 "cmd/compile/internal/types2"
15 "cmd/internal/src"
16 )
17
18
19
20
21
22
23 type ImplicitNode interface {
24 ir.Node
25 SetImplicit(x bool)
26 }
27
28
29 func Implicit(n ImplicitNode) ImplicitNode {
30 n.SetImplicit(true)
31 return n
32 }
33
34
35 func typed(typ *types.Type, n ir.Node) ir.Node {
36 n.SetType(typ)
37 n.SetTypecheck(1)
38 return n
39 }
40
41
42
43
44
45 func FixValue(typ *types.Type, val constant.Value) constant.Value {
46 assert(typ.Kind() != types.TFORW)
47 switch {
48 case typ.IsInteger():
49 val = constant.ToInt(val)
50 case typ.IsFloat():
51 val = constant.ToFloat(val)
52 case typ.IsComplex():
53 val = constant.ToComplex(val)
54 }
55 if !typ.IsUntyped() {
56 val = typecheck.ConvertVal(val, typ, false)
57 }
58 ir.AssertValidTypeForConst(typ, val)
59 return val
60 }
61
62
63
64 func Addr(pos src.XPos, x ir.Node) *ir.AddrExpr {
65 n := typecheck.NodAddrAt(pos, x)
66 typed(types.NewPtr(x.Type()), n)
67 return n
68 }
69
70 func Deref(pos src.XPos, typ *types.Type, x ir.Node) *ir.StarExpr {
71 n := ir.NewStarExpr(pos, x)
72 typed(typ, n)
73 return n
74 }
75
76
77
78 func idealType(tv syntax.TypeAndValue) types2.Type {
79
80
81
82
83 typ := types2.Unalias(tv.Type)
84 if basic, ok := typ.(*types2.Basic); ok && basic.Info()&types2.IsUntyped != 0 {
85 switch basic.Kind() {
86 case types2.UntypedNil:
87
88
89 case types2.UntypedInt, types2.UntypedFloat, types2.UntypedComplex:
90 typ = types2.Typ[types2.Uint]
91 if tv.Value != nil {
92 s := constant.ToInt(tv.Value)
93 assert(s.Kind() == constant.Int)
94 if constant.Sign(s) < 0 {
95 typ = types2.Typ[types2.Int]
96 }
97 }
98 case types2.UntypedBool:
99 typ = types2.Typ[types2.Bool]
100 case types2.UntypedString:
101 typ = types2.Typ[types2.String]
102 case types2.UntypedRune:
103 typ = types2.Typ[types2.Int32]
104 default:
105 return nil
106 }
107 }
108 return typ
109 }
110
111 func isTypeParam(t types2.Type) bool {
112 _, ok := types2.Unalias(t).(*types2.TypeParam)
113 return ok
114 }
115
116
117
118 func isNotInHeap(typ types2.Type) bool {
119 typ = types2.Unalias(typ)
120 if named, ok := typ.(*types2.Named); ok {
121 if obj := named.Obj(); obj.Name() == "nih" && obj.Pkg().Path() == "runtime/internal/sys" {
122 return true
123 }
124 typ = named.Underlying()
125 }
126
127 switch typ := typ.(type) {
128 case *types2.Array:
129 return isNotInHeap(typ.Elem())
130 case *types2.Struct:
131 for i := 0; i < typ.NumFields(); i++ {
132 if isNotInHeap(typ.Field(i).Type()) {
133 return true
134 }
135 }
136 return false
137 default:
138 return false
139 }
140 }
141
View as plain text