1
2
3
4
5 package typecheck
6
7 import (
8 "fmt"
9 "sync"
10
11 "cmd/compile/internal/base"
12 "cmd/compile/internal/ir"
13 "cmd/compile/internal/types"
14 "cmd/internal/src"
15 )
16
17 var funcStack []*ir.Func
18
19
20
21
22
23
24 func DeclFunc(fn *ir.Func) {
25 fn.DeclareParams(true)
26 fn.Nname.Defn = fn
27 Target.Funcs = append(Target.Funcs, fn)
28
29 funcStack = append(funcStack, ir.CurFunc)
30 ir.CurFunc = fn
31 }
32
33
34
35 func FinishFuncBody() {
36 funcStack, ir.CurFunc = funcStack[:len(funcStack)-1], funcStack[len(funcStack)-1]
37 }
38
39 func CheckFuncStack() {
40 if len(funcStack) != 0 {
41 base.Fatalf("funcStack is non-empty: %v", len(funcStack))
42 }
43 }
44
45
46
47
48
49
50
51 func TempAt(pos src.XPos, curfn *ir.Func, typ *types.Type) *ir.Name {
52 if curfn == nil {
53 base.FatalfAt(pos, "no curfn for TempAt")
54 }
55 if typ == nil {
56 base.FatalfAt(pos, "TempAt called with nil type")
57 }
58 if typ.Kind() == types.TFUNC && typ.Recv() != nil {
59 base.FatalfAt(pos, "misuse of method type: %v", typ)
60 }
61 types.CalcSize(typ)
62
63 sym := &types.Sym{
64 Name: autotmpname(len(curfn.Dcl)),
65 Pkg: types.LocalPkg,
66 }
67 name := curfn.NewLocal(pos, sym, typ)
68 name.SetEsc(ir.EscNever)
69 name.SetUsed(true)
70 name.SetAutoTemp(true)
71
72 return name
73 }
74
75 var (
76 autotmpnamesmu sync.Mutex
77 autotmpnames []string
78 )
79
80
81 func autotmpname(n int) string {
82 autotmpnamesmu.Lock()
83 defer autotmpnamesmu.Unlock()
84
85
86 if n >= len(autotmpnames) {
87 autotmpnames = append(autotmpnames, make([]string, n+1-len(autotmpnames))...)
88 autotmpnames = autotmpnames[:cap(autotmpnames)]
89 }
90
91 s := autotmpnames[n]
92 if s == "" {
93
94
95 prefix := ".autotmp_%d"
96
97 s = fmt.Sprintf(prefix, n)
98 autotmpnames[n] = s
99 }
100 return s
101 }
102
103
104
105 func NewMethodType(sig *types.Type, recv *types.Type) *types.Type {
106 nrecvs := 0
107 if recv != nil {
108 nrecvs++
109 }
110
111
112
113
114 params := make([]*types.Field, nrecvs+sig.NumParams())
115 if recv != nil {
116 params[0] = types.NewField(base.Pos, nil, recv)
117 }
118 for i, param := range sig.Params() {
119 d := types.NewField(base.Pos, nil, param.Type)
120 d.SetIsDDD(param.IsDDD())
121 params[nrecvs+i] = d
122 }
123
124 results := make([]*types.Field, sig.NumResults())
125 for i, t := range sig.Results() {
126 results[i] = types.NewField(base.Pos, nil, t.Type)
127 }
128
129 return types.NewSignature(nil, params, results)
130 }
131
View as plain text