1
2
3
4
5 package noder
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/compile/internal/syntax"
11 "cmd/compile/internal/typecheck"
12 "cmd/compile/internal/types"
13 "cmd/compile/internal/types2"
14 "cmd/internal/src"
15 )
16
17 func (g *irgen) def(name *syntax.Name) (*ir.Name, types2.Object) {
18 obj, ok := g.info.Defs[name]
19 if !ok {
20 base.FatalfAt(g.pos(name), "unknown name %v", name)
21 }
22 return g.obj(obj), obj
23 }
24
25
26
27
28 func (g *irgen) use(name *syntax.Name) ir.Node {
29 obj2, ok := g.info.Uses[name]
30 if !ok {
31 base.FatalfAt(g.pos(name), "unknown name %v", name)
32 }
33 obj := ir.CaptureName(g.pos(name), ir.CurFunc, g.obj(obj2))
34 if obj.Defn != nil && obj.Defn.Op() == ir.ONAME {
35
36
37 obj.SetTypecheck(1)
38 obj.SetType(obj.Defn.Type())
39 }
40
41 if obj.Class == ir.PFUNC {
42 if inst, ok := g.info.Instances[name]; ok {
43
44
45 targs := make([]ir.Node, inst.TypeArgs.Len())
46 for i := range targs {
47 targs[i] = ir.TypeNode(g.typ(inst.TypeArgs.At(i)))
48 }
49 typ := g.substType(obj.Type(), obj.Type().TParams(), targs)
50 return typed(typ, ir.NewInstExpr(g.pos(name), ir.OFUNCINST, obj, targs))
51 }
52 }
53
54 return obj
55 }
56
57
58
59
60
61
62
63 func (g *irgen) obj(obj types2.Object) *ir.Name {
64
65
66 if obj.Pkg() != g.self {
67 if sig, ok := obj.Type().(*types2.Signature); ok && sig.Recv() != nil {
68
69
70 base.FatalfAt(g.pos(obj), "tried to import a method directly")
71 }
72 sym := g.sym(obj)
73 if sym.Def != nil {
74 return sym.Def.(*ir.Name)
75 }
76 n := typecheck.Resolve(ir.NewIdent(src.NoXPos, sym))
77 if n, ok := n.(*ir.Name); ok {
78 n.SetTypecheck(1)
79 return n
80 }
81 base.FatalfAt(g.pos(obj), "failed to resolve %v", obj)
82 }
83
84 if name, ok := g.objs[obj]; ok {
85 return name
86 }
87
88 var name *ir.Name
89 pos := g.pos(obj)
90
91 class := typecheck.DeclContext
92 if obj.Parent() == g.self.Scope() {
93 class = ir.PEXTERN
94 }
95
96
97 switch obj := obj.(type) {
98 case *types2.Const:
99 name = g.objCommon(pos, ir.OLITERAL, g.sym(obj), class, g.typ(obj.Type()))
100
101 case *types2.Func:
102 sig := obj.Type().(*types2.Signature)
103 var sym *types.Sym
104 var typ *types.Type
105 if recv := sig.Recv(); recv == nil {
106 if obj.Name() == "init" {
107 sym = renameinit()
108 } else {
109 sym = g.sym(obj)
110 }
111 typ = g.typ(sig)
112 } else {
113 sym = g.selector(obj)
114 if !sym.IsBlank() {
115 sym = ir.MethodSym(g.typ(recv.Type()), sym)
116 }
117 typ = g.signature(g.param(recv), sig)
118 }
119 name = g.objCommon(pos, ir.ONAME, sym, ir.PFUNC, typ)
120
121 case *types2.TypeName:
122 if obj.IsAlias() {
123 name = g.objCommon(pos, ir.OTYPE, g.sym(obj), class, g.typ(obj.Type()))
124 name.SetAlias(true)
125 } else {
126 name = ir.NewDeclNameAt(pos, ir.OTYPE, g.sym(obj))
127 g.objFinish(name, class, types.NewNamed(name))
128 }
129
130 case *types2.Var:
131 sym := g.sym(obj)
132 if class == ir.PPARAMOUT && (sym == nil || sym.IsBlank()) {
133
134
135 nresults := 0
136 for _, n := range ir.CurFunc.Dcl {
137 if n.Class == ir.PPARAMOUT {
138 nresults++
139 }
140 }
141 if sym == nil {
142 sym = typecheck.LookupNum("~r", nresults)
143 } else {
144 sym = typecheck.LookupNum("~b", nresults)
145 }
146 }
147 name = g.objCommon(pos, ir.ONAME, sym, class, g.typ(obj.Type()))
148
149 default:
150 g.unhandled("object", obj)
151 }
152
153 g.objs[obj] = name
154 name.SetTypecheck(1)
155 return name
156 }
157
158 func (g *irgen) objCommon(pos src.XPos, op ir.Op, sym *types.Sym, class ir.Class, typ *types.Type) *ir.Name {
159 name := ir.NewDeclNameAt(pos, op, sym)
160 g.objFinish(name, class, typ)
161 return name
162 }
163
164 func (g *irgen) objFinish(name *ir.Name, class ir.Class, typ *types.Type) {
165 sym := name.Sym()
166
167 name.SetType(typ)
168 name.Class = class
169 if name.Class == ir.PFUNC {
170 sym.SetFunc(true)
171 }
172
173 name.SetTypecheck(1)
174 name.SetWalkdef(1)
175
176 if ir.IsBlank(name) {
177 return
178 }
179
180 switch class {
181 case ir.PEXTERN:
182 g.target.Externs = append(g.target.Externs, name)
183 fallthrough
184 case ir.PFUNC:
185 sym.Def = name
186 if name.Class == ir.PFUNC && name.Type().Recv() != nil {
187 break
188 }
189 if types.IsExported(sym.Name) {
190
191
192 typecheck.Export(name)
193 }
194 if base.Flag.AsmHdr != "" && !name.Sym().Asm() {
195 name.Sym().SetAsm(true)
196 g.target.Asms = append(g.target.Asms, name)
197 }
198
199 default:
200
201 name.Curfn = ir.CurFunc
202 if name.Op() == ir.ONAME {
203 ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, name)
204 }
205 }
206 }
207
View as plain text