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 func TempAt(pos src.XPos, curfn *ir.Func, typ *types.Type) *ir.Name {
47 if curfn == nil {
48 base.FatalfAt(pos, "no curfn for TempAt")
49 }
50 if typ == nil {
51 base.FatalfAt(pos, "TempAt called with nil type")
52 }
53 if typ.Kind() == types.TFUNC && typ.Recv() != nil {
54 base.FatalfAt(pos, "misuse of method type: %v", typ)
55 }
56 types.CalcSize(typ)
57
58 sym := &types.Sym{
59 Name: autotmpname(len(curfn.Dcl)),
60 Pkg: types.LocalPkg,
61 }
62 name := curfn.NewLocal(pos, sym, typ)
63 name.SetEsc(ir.EscNever)
64 name.SetUsed(true)
65 name.SetAutoTemp(true)
66
67 return name
68 }
69
70 var (
71 autotmpnamesmu sync.Mutex
72 autotmpnames []string
73 )
74
75
76 func autotmpname(n int) string {
77 autotmpnamesmu.Lock()
78 defer autotmpnamesmu.Unlock()
79
80
81 if n >= len(autotmpnames) {
82 autotmpnames = append(autotmpnames, make([]string, n+1-len(autotmpnames))...)
83 autotmpnames = autotmpnames[:cap(autotmpnames)]
84 }
85
86 s := autotmpnames[n]
87 if s == "" {
88
89
90 prefix := ".autotmp_%d"
91
92 s = fmt.Sprintf(prefix, n)
93 autotmpnames[n] = s
94 }
95 return s
96 }
97
98
99
100 func NewMethodType(sig *types.Type, recv *types.Type) *types.Type {
101 nrecvs := 0
102 if recv != nil {
103 nrecvs++
104 }
105
106
107
108
109 params := make([]*types.Field, nrecvs+sig.NumParams())
110 if recv != nil {
111 params[0] = types.NewField(base.Pos, nil, recv)
112 }
113 for i, param := range sig.Params() {
114 d := types.NewField(base.Pos, nil, param.Type)
115 d.SetIsDDD(param.IsDDD())
116 params[nrecvs+i] = d
117 }
118
119 results := make([]*types.Field, sig.NumResults())
120 for i, t := range sig.Results() {
121 results[i] = types.NewField(base.Pos, nil, t.Type)
122 }
123
124 return types.NewSignature(nil, params, results)
125 }
126
View as plain text