summaryrefslogtreecommitdiffstats
path: root/src/cmd/compile/internal/noder/object.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:16:40 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:16:40 +0000
commit47ab3d4a42e9ab51c465c4322d2ec233f6324e6b (patch)
treea61a0ffd83f4a3def4b36e5c8e99630c559aa723 /src/cmd/compile/internal/noder/object.go
parentInitial commit. (diff)
downloadgolang-1.18-47ab3d4a42e9ab51c465c4322d2ec233f6324e6b.tar.xz
golang-1.18-47ab3d4a42e9ab51c465c4322d2ec233f6324e6b.zip
Adding upstream version 1.18.10.upstream/1.18.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/cmd/compile/internal/noder/object.go')
-rw-r--r--src/cmd/compile/internal/noder/object.go206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/noder/object.go b/src/cmd/compile/internal/noder/object.go
new file mode 100644
index 0000000..37a995b
--- /dev/null
+++ b/src/cmd/compile/internal/noder/object.go
@@ -0,0 +1,206 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package noder
+
+import (
+ "cmd/compile/internal/base"
+ "cmd/compile/internal/ir"
+ "cmd/compile/internal/syntax"
+ "cmd/compile/internal/typecheck"
+ "cmd/compile/internal/types"
+ "cmd/compile/internal/types2"
+ "cmd/internal/src"
+)
+
+func (g *irgen) def(name *syntax.Name) (*ir.Name, types2.Object) {
+ obj, ok := g.info.Defs[name]
+ if !ok {
+ base.FatalfAt(g.pos(name), "unknown name %v", name)
+ }
+ return g.obj(obj), obj
+}
+
+// use returns the Name or InstExpr node associated with the use of name,
+// possibly instantiated by type arguments. The returned node will have
+// the correct type and be marked as typechecked.
+func (g *irgen) use(name *syntax.Name) ir.Node {
+ obj2, ok := g.info.Uses[name]
+ if !ok {
+ base.FatalfAt(g.pos(name), "unknown name %v", name)
+ }
+ obj := ir.CaptureName(g.pos(name), ir.CurFunc, g.obj(obj2))
+ if obj.Defn != nil && obj.Defn.Op() == ir.ONAME {
+ // If CaptureName created a closure variable, then transfer the
+ // type of the captured name to the new closure variable.
+ obj.SetTypecheck(1)
+ obj.SetType(obj.Defn.Type())
+ }
+
+ if obj.Class == ir.PFUNC {
+ if inst, ok := g.info.Instances[name]; ok {
+ // This is the case where inferring types required the
+ // types of the function arguments.
+ targs := make([]ir.Node, inst.TypeArgs.Len())
+ for i := range targs {
+ targs[i] = ir.TypeNode(g.typ(inst.TypeArgs.At(i)))
+ }
+ typ := g.substType(obj.Type(), obj.Type().TParams(), targs)
+ return typed(typ, ir.NewInstExpr(g.pos(name), ir.OFUNCINST, obj, targs))
+ }
+ }
+
+ return obj
+}
+
+// obj returns the Name that represents the given object. If no such Name exists
+// yet, it will be implicitly created. The returned node will have the correct
+// type and be marked as typechecked.
+//
+// For objects declared at function scope, ir.CurFunc must already be
+// set to the respective function when the Name is created.
+func (g *irgen) obj(obj types2.Object) *ir.Name {
+ // For imported objects, we use iimport directly instead of mapping
+ // the types2 representation.
+ if obj.Pkg() != g.self {
+ if sig, ok := obj.Type().(*types2.Signature); ok && sig.Recv() != nil {
+ // We can't import a method by name - must import the type
+ // and access the method from it.
+ base.FatalfAt(g.pos(obj), "tried to import a method directly")
+ }
+ sym := g.sym(obj)
+ if sym.Def != nil {
+ return sym.Def.(*ir.Name)
+ }
+ n := typecheck.Resolve(ir.NewIdent(src.NoXPos, sym))
+ if n, ok := n.(*ir.Name); ok {
+ n.SetTypecheck(1)
+ return n
+ }
+ base.FatalfAt(g.pos(obj), "failed to resolve %v", obj)
+ }
+
+ if name, ok := g.objs[obj]; ok {
+ return name // previously mapped
+ }
+
+ var name *ir.Name
+ pos := g.pos(obj)
+
+ class := typecheck.DeclContext
+ if obj.Parent() == g.self.Scope() {
+ class = ir.PEXTERN // forward reference to package-block declaration
+ }
+
+ // "You are in a maze of twisting little passages, all different."
+ switch obj := obj.(type) {
+ case *types2.Const:
+ name = g.objCommon(pos, ir.OLITERAL, g.sym(obj), class, g.typ(obj.Type()))
+
+ case *types2.Func:
+ sig := obj.Type().(*types2.Signature)
+ var sym *types.Sym
+ var typ *types.Type
+ if recv := sig.Recv(); recv == nil {
+ if obj.Name() == "init" {
+ sym = renameinit()
+ } else {
+ sym = g.sym(obj)
+ }
+ typ = g.typ(sig)
+ } else {
+ sym = g.selector(obj)
+ if !sym.IsBlank() {
+ sym = ir.MethodSym(g.typ(recv.Type()), sym)
+ }
+ typ = g.signature(g.param(recv), sig)
+ }
+ name = g.objCommon(pos, ir.ONAME, sym, ir.PFUNC, typ)
+
+ case *types2.TypeName:
+ if obj.IsAlias() {
+ name = g.objCommon(pos, ir.OTYPE, g.sym(obj), class, g.typ(obj.Type()))
+ name.SetAlias(true)
+ } else {
+ name = ir.NewDeclNameAt(pos, ir.OTYPE, g.sym(obj))
+ g.objFinish(name, class, types.NewNamed(name))
+ }
+
+ case *types2.Var:
+ sym := g.sym(obj)
+ if class == ir.PPARAMOUT && (sym == nil || sym.IsBlank()) {
+ // Backend needs names for result parameters,
+ // even if they're anonymous or blank.
+ nresults := 0
+ for _, n := range ir.CurFunc.Dcl {
+ if n.Class == ir.PPARAMOUT {
+ nresults++
+ }
+ }
+ if sym == nil {
+ sym = typecheck.LookupNum("~r", nresults) // 'r' for "result"
+ } else {
+ sym = typecheck.LookupNum("~b", nresults) // 'b' for "blank"
+ }
+ }
+ name = g.objCommon(pos, ir.ONAME, sym, class, g.typ(obj.Type()))
+
+ default:
+ g.unhandled("object", obj)
+ }
+
+ g.objs[obj] = name
+ name.SetTypecheck(1)
+ return name
+}
+
+func (g *irgen) objCommon(pos src.XPos, op ir.Op, sym *types.Sym, class ir.Class, typ *types.Type) *ir.Name {
+ name := ir.NewDeclNameAt(pos, op, sym)
+ g.objFinish(name, class, typ)
+ return name
+}
+
+func (g *irgen) objFinish(name *ir.Name, class ir.Class, typ *types.Type) {
+ sym := name.Sym()
+
+ name.SetType(typ)
+ name.Class = class
+ if name.Class == ir.PFUNC {
+ sym.SetFunc(true)
+ }
+
+ name.SetTypecheck(1)
+ name.SetWalkdef(1)
+
+ if ir.IsBlank(name) {
+ return
+ }
+
+ switch class {
+ case ir.PEXTERN:
+ g.target.Externs = append(g.target.Externs, name)
+ fallthrough
+ case ir.PFUNC:
+ sym.Def = name
+ if name.Class == ir.PFUNC && name.Type().Recv() != nil {
+ break // methods are exported with their receiver type
+ }
+ if types.IsExported(sym.Name) {
+ // Generic functions can be marked for export here, even
+ // though they will not be compiled until instantiated.
+ typecheck.Export(name)
+ }
+ if base.Flag.AsmHdr != "" && !name.Sym().Asm() {
+ name.Sym().SetAsm(true)
+ g.target.Asms = append(g.target.Asms, name)
+ }
+
+ default:
+ // Function-scoped declaration.
+ name.Curfn = ir.CurFunc
+ if name.Op() == ir.ONAME {
+ ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, name)
+ }
+ }
+}