github.com/bir3/gocompiler@v0.3.205/src/cmd/compile/internal/noder/object.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package noder 6 7 import ( 8 "github.com/bir3/gocompiler/src/cmd/compile/internal/base" 9 "github.com/bir3/gocompiler/src/cmd/compile/internal/ir" 10 "github.com/bir3/gocompiler/src/cmd/compile/internal/syntax" 11 "github.com/bir3/gocompiler/src/cmd/compile/internal/typecheck" 12 "github.com/bir3/gocompiler/src/cmd/compile/internal/types" 13 "github.com/bir3/gocompiler/src/cmd/compile/internal/types2" 14 "github.com/bir3/gocompiler/src/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 // use returns the Name or InstExpr node associated with the use of name, 26 // possibly instantiated by type arguments. The returned node will have 27 // the correct type and be marked as typechecked. 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 // If CaptureName created a closure variable, then transfer the 36 // type of the captured name to the new closure variable. 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 // This is the case where inferring types required the 44 // types of the function arguments. 45 targs := make([]ir.Ntype, 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 // obj returns the Name that represents the given object. If no such Name exists 58 // yet, it will be implicitly created. The returned node will have the correct 59 // type and be marked as typechecked. 60 // 61 // For objects declared at function scope, ir.CurFunc must already be 62 // set to the respective function when the Name is created. 63 func (g *irgen) obj(obj types2.Object) *ir.Name { 64 // For imported objects, we use iimport directly instead of mapping 65 // the types2 representation. 66 if obj.Pkg() != g.self { 67 if sig, ok := obj.Type().(*types2.Signature); ok && sig.Recv() != nil { 68 // We can't import a method by name - must import the type 69 // and access the method from it. 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 // previously mapped 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 // forward reference to package-block declaration 94 } 95 96 // "You are in a maze of twisting little passages, all different." 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 // Backend needs names for result parameters, 134 // even if they're anonymous or blank. 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) // 'r' for "result" 143 } else { 144 sym = typecheck.LookupNum("~b", nresults) // 'b' for "blank" 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 175 if ir.IsBlank(name) { 176 return 177 } 178 179 switch class { 180 case ir.PEXTERN: 181 g.target.Externs = append(g.target.Externs, name) 182 fallthrough 183 case ir.PFUNC: 184 sym.Def = name 185 if name.Class == ir.PFUNC && name.Type().Recv() != nil { 186 break // methods are exported with their receiver type 187 } 188 if types.IsExported(sym.Name) { 189 // Generic functions can be marked for export here, even 190 // though they will not be compiled until instantiated. 191 typecheck.Export(name) 192 } 193 if base.Flag.AsmHdr != "" && !name.Sym().Asm() { 194 name.Sym().SetAsm(true) 195 g.target.Asms = append(g.target.Asms, name) 196 } 197 198 default: 199 // Function-scoped declaration. 200 name.Curfn = ir.CurFunc 201 if name.Op() == ir.ONAME { 202 ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, name) 203 } 204 } 205 }