1
2
3
4
5 package typecheck
6
7 import (
8 "go/constant"
9
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/ir"
12 "cmd/compile/internal/types"
13 )
14
15
16 func tcArrayType(n *ir.ArrayType) ir.Node {
17 n.Elem = typecheckNtype(n.Elem)
18 if n.Elem.Type() == nil {
19 return n
20 }
21 if n.Len == nil {
22 if !n.Diag() {
23 n.SetDiag(true)
24 base.Errorf("use of [...] array outside of array literal")
25 }
26 return n
27 }
28 n.Len = indexlit(Expr(n.Len))
29 size := n.Len
30 if ir.ConstType(size) != constant.Int {
31 switch {
32 case size.Type() == nil:
33
34 case size.Type().IsInteger() && size.Op() != ir.OLITERAL:
35 base.Errorf("non-constant array bound %v", size)
36 default:
37 base.Errorf("invalid array bound %v", size)
38 }
39 return n
40 }
41
42 v := size.Val()
43 if ir.ConstOverflow(v, types.Types[types.TINT]) {
44 base.Errorf("array bound is too large")
45 return n
46 }
47
48 if constant.Sign(v) < 0 {
49 base.Errorf("array bound must be non-negative")
50 return n
51 }
52
53 bound, _ := constant.Int64Val(v)
54 t := types.NewArray(n.Elem.Type(), bound)
55 n.SetOTYPE(t)
56 types.CheckSize(t)
57 return n
58 }
59
60
61 func tcChanType(n *ir.ChanType) ir.Node {
62 n.Elem = typecheckNtype(n.Elem)
63 l := n.Elem
64 if l.Type() == nil {
65 return n
66 }
67 if l.Type().NotInHeap() {
68 base.Errorf("chan of incomplete (or unallocatable) type not allowed")
69 }
70 n.SetOTYPE(types.NewChan(l.Type(), n.Dir))
71 return n
72 }
73
74
75 func tcFuncType(n *ir.FuncType) ir.Node {
76 misc := func(f *types.Field, nf *ir.Field) {
77 f.SetIsDDD(nf.IsDDD)
78 if nf.Decl != nil {
79 nf.Decl.SetType(f.Type)
80 f.Nname = nf.Decl
81 }
82 }
83
84 lno := base.Pos
85
86 var recv *types.Field
87 if n.Recv != nil {
88 recv = tcField(n.Recv, misc)
89 }
90
91 t := types.NewSignature(types.LocalPkg, recv, nil, tcFields(n.Params, misc), tcFields(n.Results, misc))
92 checkdupfields("argument", t.Recvs().FieldSlice(), t.Params().FieldSlice(), t.Results().FieldSlice())
93
94 base.Pos = lno
95
96 n.SetOTYPE(t)
97 return n
98 }
99
100
101 func tcInterfaceType(n *ir.InterfaceType) ir.Node {
102 if len(n.Methods) == 0 {
103 n.SetOTYPE(types.Types[types.TINTER])
104 return n
105 }
106
107 lno := base.Pos
108 methods := tcFields(n.Methods, nil)
109 base.Pos = lno
110
111 n.SetOTYPE(types.NewInterface(types.LocalPkg, methods, false))
112 return n
113 }
114
115
116 func tcMapType(n *ir.MapType) ir.Node {
117 n.Key = typecheckNtype(n.Key)
118 n.Elem = typecheckNtype(n.Elem)
119 l := n.Key
120 r := n.Elem
121 if l.Type() == nil || r.Type() == nil {
122 return n
123 }
124 if l.Type().NotInHeap() {
125 base.Errorf("incomplete (or unallocatable) map key not allowed")
126 }
127 if r.Type().NotInHeap() {
128 base.Errorf("incomplete (or unallocatable) map value not allowed")
129 }
130 n.SetOTYPE(types.NewMap(l.Type(), r.Type()))
131 mapqueue = append(mapqueue, n)
132 return n
133 }
134
135
136 func tcSliceType(n *ir.SliceType) ir.Node {
137 n.Elem = typecheckNtype(n.Elem)
138 if n.Elem.Type() == nil {
139 return n
140 }
141 t := types.NewSlice(n.Elem.Type())
142 n.SetOTYPE(t)
143 types.CheckSize(t)
144 return n
145 }
146
147
148 func tcStructType(n *ir.StructType) ir.Node {
149 lno := base.Pos
150
151 fields := tcFields(n.Fields, func(f *types.Field, nf *ir.Field) {
152 if nf.Embedded {
153 checkembeddedtype(f.Type)
154 f.Embedded = 1
155 }
156 f.Note = nf.Note
157 })
158 checkdupfields("field", fields)
159
160 base.Pos = lno
161 n.SetOTYPE(types.NewStruct(types.LocalPkg, fields))
162 return n
163 }
164
165
166
167 func tcField(n *ir.Field, misc func(*types.Field, *ir.Field)) *types.Field {
168 base.Pos = n.Pos
169 if n.Ntype != nil {
170 n.Type = typecheckNtype(n.Ntype).Type()
171 n.Ntype = nil
172 }
173 f := types.NewField(n.Pos, n.Sym, n.Type)
174 if misc != nil {
175 misc(f, n)
176 }
177 return f
178 }
179
180
181
182 func tcFields(l []*ir.Field, misc func(*types.Field, *ir.Field)) []*types.Field {
183 fields := make([]*types.Field, len(l))
184 for i, n := range l {
185 fields[i] = tcField(n, misc)
186 }
187 return fields
188 }
189
View as plain text