Commit 16e6cd9a authored by Austin Clements's avatar Austin Clements

cmd/compile: mark function Syms

In order to mark the obj.LSyms produced by the compiler with the
correct ABI, we need to know which types.Syms refer to function
symbols. This CL adds a flag to types.Syms to mark symbols for
functions, and sets this flag everywhere we create a PFUNC-class node,
and in the one place where we directly create function symbols without
always wrapping them in a PFUNC node (methodSym).

We'll use this information to construct obj.LSyms with correct ABI
information.

For #27539.

Change-Id: Ie3ac8bf3da013e449e78f6ca85546a055f275463
Reviewed-on: https://go-review.googlesource.com/c/147158
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarDavid Chase <drchase@google.com>
Reviewed-by: 's avatarKeith Randall <khr@golang.org>
parent c5718b6b
...@@ -330,6 +330,7 @@ func hashfor(t *types.Type) *Node { ...@@ -330,6 +330,7 @@ func hashfor(t *types.Type) *Node {
n := newname(sym) n := newname(sym)
n.SetClass(PFUNC) n.SetClass(PFUNC)
n.Sym.SetFunc(true)
n.Type = functype(nil, []*Node{ n.Type = functype(nil, []*Node{
anonfield(types.NewPtr(t)), anonfield(types.NewPtr(t)),
anonfield(types.Types[TUINTPTR]), anonfield(types.Types[TUINTPTR]),
......
...@@ -125,6 +125,9 @@ func declare(n *Node, ctxt Class) { ...@@ -125,6 +125,9 @@ func declare(n *Node, ctxt Class) {
s.Def = asTypesNode(n) s.Def = asTypesNode(n)
n.Name.Vargen = int32(gen) n.Name.Vargen = int32(gen)
n.SetClass(ctxt) n.SetClass(ctxt)
if ctxt == PFUNC {
n.Sym.SetFunc(true)
}
autoexport(n, ctxt) autoexport(n, ctxt)
} }
...@@ -801,8 +804,12 @@ func origSym(s *types.Sym) *types.Sym { ...@@ -801,8 +804,12 @@ func origSym(s *types.Sym) *types.Sym {
// Method symbols can be used to distinguish the same method appearing // Method symbols can be used to distinguish the same method appearing
// in different method sets. For example, T.M and (*T).M have distinct // in different method sets. For example, T.M and (*T).M have distinct
// method symbols. // method symbols.
//
// The returned symbol will be marked as a function.
func methodSym(recv *types.Type, msym *types.Sym) *types.Sym { func methodSym(recv *types.Type, msym *types.Sym) *types.Sym {
return methodSymSuffix(recv, msym, "") sym := methodSymSuffix(recv, msym, "")
sym.SetFunc(true)
return sym
} }
// methodSymSuffix is like methodsym, but allows attaching a // methodSymSuffix is like methodsym, but allows attaching a
......
...@@ -140,6 +140,9 @@ func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t ...@@ -140,6 +140,9 @@ func importobj(ipkg *types.Pkg, pos src.XPos, s *types.Sym, op Op, ctxt Class, t
n.Op = op n.Op = op
n.Pos = pos n.Pos = pos
n.SetClass(ctxt) n.SetClass(ctxt)
if ctxt == PFUNC {
n.Sym.SetFunc(true)
}
n.Type = t n.Type = t
return n return n
} }
......
...@@ -334,6 +334,7 @@ func (r *importReader) doDecl(n *Node) { ...@@ -334,6 +334,7 @@ func (r *importReader) doDecl(n *Node) {
m := newfuncnamel(mpos, methodSym(recv.Type, msym)) m := newfuncnamel(mpos, methodSym(recv.Type, msym))
m.Type = mtyp m.Type = mtyp
m.SetClass(PFUNC) m.SetClass(PFUNC)
// methodSym already marked m.Sym as a function.
// (comment from parser.go) // (comment from parser.go)
// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as // inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
......
...@@ -649,6 +649,11 @@ func Main(archInit func(*Arch)) { ...@@ -649,6 +649,11 @@ func Main(archInit func(*Arch)) {
Curfn = nil Curfn = nil
peekitabs() peekitabs()
// The "init" function is the only user-spellable symbol that
// we construct later. Mark it as a function now before
// anything can ask for its Linksym.
lookup("init").SetFunc(true)
// Phase 8: Compile top level functions. // Phase 8: Compile top level functions.
// Don't use range--walk can add functions to xtop. // Don't use range--walk can add functions to xtop.
timings.Start("be", "compilefuncs") timings.Start("be", "compilefuncs")
......
...@@ -3670,6 +3670,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value { ...@@ -3670,6 +3670,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
n2 := newnamel(fn.Pos, fn.Sym) n2 := newnamel(fn.Pos, fn.Sym)
n2.Name.Curfn = s.curfn n2.Name.Curfn = s.curfn
n2.SetClass(PFUNC) n2.SetClass(PFUNC)
n2.Sym.SetFunc(true)
n2.Pos = fn.Pos n2.Pos = fn.Pos
n2.Type = types.Types[TUINT8] // dummy type for a static closure. Could use runtime.funcval if we had it. n2.Type = types.Types[TUINT8] // dummy type for a static closure. Could use runtime.funcval if we had it.
closure = s.expr(n2) closure = s.expr(n2)
......
...@@ -1619,6 +1619,7 @@ func hashmem(t *types.Type) *Node { ...@@ -1619,6 +1619,7 @@ func hashmem(t *types.Type) *Node {
n := newname(sym) n := newname(sym)
n.SetClass(PFUNC) n.SetClass(PFUNC)
n.Sym.SetFunc(true)
n.Type = functype(nil, []*Node{ n.Type = functype(nil, []*Node{
anonfield(types.NewPtr(t)), anonfield(types.NewPtr(t)),
anonfield(types.Types[TUINTPTR]), anonfield(types.Types[TUINTPTR]),
......
...@@ -2513,6 +2513,7 @@ func typecheckMethodExpr(n *Node) (res *Node) { ...@@ -2513,6 +2513,7 @@ func typecheckMethodExpr(n *Node) (res *Node) {
n.Type = methodfunc(m.Type, n.Left.Type) n.Type = methodfunc(m.Type, n.Left.Type)
n.Xoffset = 0 n.Xoffset = 0
n.SetClass(PFUNC) n.SetClass(PFUNC)
// methodSym already marked n.Sym as a function.
return n return n
} }
......
...@@ -3063,6 +3063,7 @@ func eqfor(t *types.Type) (n *Node, needsize bool) { ...@@ -3063,6 +3063,7 @@ func eqfor(t *types.Type) (n *Node, needsize bool) {
sym := typesymprefix(".eq", t) sym := typesymprefix(".eq", t)
n := newname(sym) n := newname(sym)
n.SetClass(PFUNC) n.SetClass(PFUNC)
n.Sym.SetFunc(true)
n.Type = functype(nil, []*Node{ n.Type = functype(nil, []*Node{
anonfield(types.NewPtr(t)), anonfield(types.NewPtr(t)),
anonfield(types.NewPtr(t)), anonfield(types.NewPtr(t)),
......
...@@ -42,6 +42,7 @@ const ( ...@@ -42,6 +42,7 @@ const (
symSiggen // type symbol has been generated symSiggen // type symbol has been generated
symAsm // on asmlist, for writing to -asmhdr symAsm // on asmlist, for writing to -asmhdr
symAlgGen // algorithm table has been generated symAlgGen // algorithm table has been generated
symFunc // function symbol; uses internal ABI
) )
func (sym *Sym) OnExportList() bool { return sym.flags&symOnExportList != 0 } func (sym *Sym) OnExportList() bool { return sym.flags&symOnExportList != 0 }
...@@ -49,12 +50,14 @@ func (sym *Sym) Uniq() bool { return sym.flags&symUniq != 0 } ...@@ -49,12 +50,14 @@ func (sym *Sym) Uniq() bool { return sym.flags&symUniq != 0 }
func (sym *Sym) Siggen() bool { return sym.flags&symSiggen != 0 } func (sym *Sym) Siggen() bool { return sym.flags&symSiggen != 0 }
func (sym *Sym) Asm() bool { return sym.flags&symAsm != 0 } func (sym *Sym) Asm() bool { return sym.flags&symAsm != 0 }
func (sym *Sym) AlgGen() bool { return sym.flags&symAlgGen != 0 } func (sym *Sym) AlgGen() bool { return sym.flags&symAlgGen != 0 }
func (sym *Sym) Func() bool { return sym.flags&symFunc != 0 }
func (sym *Sym) SetOnExportList(b bool) { sym.flags.set(symOnExportList, b) } func (sym *Sym) SetOnExportList(b bool) { sym.flags.set(symOnExportList, b) }
func (sym *Sym) SetUniq(b bool) { sym.flags.set(symUniq, b) } func (sym *Sym) SetUniq(b bool) { sym.flags.set(symUniq, b) }
func (sym *Sym) SetSiggen(b bool) { sym.flags.set(symSiggen, b) } func (sym *Sym) SetSiggen(b bool) { sym.flags.set(symSiggen, b) }
func (sym *Sym) SetAsm(b bool) { sym.flags.set(symAsm, b) } func (sym *Sym) SetAsm(b bool) { sym.flags.set(symAsm, b) }
func (sym *Sym) SetAlgGen(b bool) { sym.flags.set(symAlgGen, b) } func (sym *Sym) SetAlgGen(b bool) { sym.flags.set(symAlgGen, b) }
func (sym *Sym) SetFunc(b bool) { sym.flags.set(symFunc, b) }
func (sym *Sym) IsBlank() bool { func (sym *Sym) IsBlank() bool {
return sym != nil && sym.Name == "_" return sym != nil && sym.Name == "_"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment