2015-02-13 14:40:36 -05:00
|
|
|
// Copyright 2009 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 gc
|
|
|
|
|
|
|
|
|
|
import (
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
"cmd/compile/internal/types"
|
2016-12-06 17:08:06 -08:00
|
|
|
"cmd/internal/src"
|
2015-02-13 14:40:36 -05:00
|
|
|
"fmt"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// Declaration stack & operations
|
|
|
|
|
|
2016-04-05 14:20:04 -07:00
|
|
|
var externdcl []*Node
|
|
|
|
|
|
|
|
|
|
var blockgen int32 // max block number
|
|
|
|
|
|
|
|
|
|
var block int32 // current block number
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// dclstack maintains a stack of shadowed symbol declarations so that
|
|
|
|
|
// popdcl can restore their declarations when a block scope ends.
|
|
|
|
|
// The stack is maintained as a linked list, using Sym's Link field.
|
|
|
|
|
//
|
|
|
|
|
// In practice, the "stack" actually ends up forming a tree: goto and label
|
|
|
|
|
// statements record the current state of dclstack so that checkgoto can
|
|
|
|
|
// validate that a goto statement does not jump over any declarations or
|
|
|
|
|
// into a new block scope.
|
|
|
|
|
//
|
|
|
|
|
// Finally, the Syms in this list are not "real" Syms as they don't actually
|
|
|
|
|
// represent object names. Sym is just a convenient type for saving shadowed
|
|
|
|
|
// Sym definitions, and only a subset of its fields are actually used.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
var dclstack *types.Sym
|
2016-04-05 12:48:49 -07:00
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func dcopy(a, b *types.Sym) {
|
2015-02-13 14:40:36 -05:00
|
|
|
a.Pkg = b.Pkg
|
|
|
|
|
a.Name = b.Name
|
|
|
|
|
a.Def = b.Def
|
|
|
|
|
a.Block = b.Block
|
|
|
|
|
a.Lastlineno = b.Lastlineno
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func push() *types.Sym {
|
|
|
|
|
d := new(types.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
d.Lastlineno = lineno
|
|
|
|
|
d.Link = dclstack
|
|
|
|
|
dclstack = d
|
|
|
|
|
return d
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// pushdcl pushes the current declaration for symbol s (if any) so that
|
|
|
|
|
// it can be shadowed by a new declaration within a nested block scope.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func pushdcl(s *types.Sym) *types.Sym {
|
2015-02-23 16:07:24 -05:00
|
|
|
d := push()
|
2015-02-13 14:40:36 -05:00
|
|
|
dcopy(d, s)
|
|
|
|
|
return d
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// popdcl pops the innermost block scope and restores all symbol declarations
|
|
|
|
|
// to their previous state.
|
2017-04-07 19:50:31 +00:00
|
|
|
func popdcl() {
|
2016-03-02 11:01:25 -08:00
|
|
|
d := dclstack
|
|
|
|
|
for ; d != nil && d.Name != ""; d = d.Link {
|
2017-03-30 13:19:18 -07:00
|
|
|
s := d.Pkg.Lookup(d.Name)
|
2016-03-02 11:01:25 -08:00
|
|
|
lno := s.Lastlineno
|
2015-02-13 14:40:36 -05:00
|
|
|
dcopy(s, d)
|
2016-03-02 11:01:25 -08:00
|
|
|
d.Lastlineno = lno
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if d == nil {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("popdcl: no mark")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-02 11:01:25 -08:00
|
|
|
|
|
|
|
|
dclstack = d.Link // pop mark
|
2015-02-13 14:40:36 -05:00
|
|
|
block = d.Block
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// markdcl records the start of a new block scope for declarations.
|
2017-04-07 19:50:31 +00:00
|
|
|
func markdcl() {
|
2015-02-23 16:07:24 -05:00
|
|
|
d := push()
|
2015-02-13 14:40:36 -05:00
|
|
|
d.Name = "" // used as a mark in fifo
|
|
|
|
|
d.Block = block
|
|
|
|
|
|
|
|
|
|
blockgen++
|
|
|
|
|
block = blockgen
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-18 17:21:32 -07:00
|
|
|
// keep around for debugging
|
|
|
|
|
func dumpdclstack() {
|
2015-02-23 16:07:24 -05:00
|
|
|
i := 0
|
|
|
|
|
for d := dclstack; d != nil; d = d.Link {
|
2016-03-18 17:21:32 -07:00
|
|
|
fmt.Printf("%6d %p", i, d)
|
|
|
|
|
if d.Name != "" {
|
2017-03-30 13:19:18 -07:00
|
|
|
fmt.Printf(" '%s' %v\n", d.Name, d.Pkg.Lookup(d.Name))
|
2016-03-18 17:21:32 -07:00
|
|
|
} else {
|
|
|
|
|
fmt.Printf(" ---\n")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-18 17:21:32 -07:00
|
|
|
i++
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func testdclstack() {
|
2015-02-23 16:07:24 -05:00
|
|
|
for d := dclstack; d != nil; d = d.Link {
|
2015-02-13 14:40:36 -05:00
|
|
|
if d.Name == "" {
|
|
|
|
|
if nerrors != 0 {
|
|
|
|
|
errorexit()
|
|
|
|
|
}
|
2017-03-14 09:46:45 -07:00
|
|
|
Fatalf("mark left on the stack")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// redeclare emits a diagnostic about symbol s being redeclared somewhere.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func redeclare(s *types.Sym, where string) {
|
2016-12-07 16:02:42 -08:00
|
|
|
if !s.Lastlineno.IsKnown() {
|
2015-03-02 16:03:26 -05:00
|
|
|
var tmp string
|
2015-02-13 14:40:36 -05:00
|
|
|
if s.Origpkg != nil {
|
|
|
|
|
tmp = s.Origpkg.Path
|
|
|
|
|
} else {
|
|
|
|
|
tmp = s.Pkg.Path
|
|
|
|
|
}
|
2015-02-23 16:07:24 -05:00
|
|
|
pkgstr := tmp
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("%v redeclared %s\n"+
|
2016-09-09 21:08:46 -07:00
|
|
|
"\tprevious declaration during import %q", s, where, pkgstr)
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
2016-03-02 11:01:25 -08:00
|
|
|
line1 := lineno
|
|
|
|
|
line2 := s.Lastlineno
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// When an import and a declaration collide in separate files,
|
|
|
|
|
// present the import as the "redeclared", because the declaration
|
|
|
|
|
// is visible where the import is, but not vice versa.
|
|
|
|
|
// See issue 4510.
|
|
|
|
|
if s.Def == nil {
|
|
|
|
|
line2 = line1
|
2016-03-02 11:01:25 -08:00
|
|
|
line1 = s.Lastlineno
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-09 21:08:46 -07:00
|
|
|
yyerrorl(line1, "%v redeclared %s\n"+
|
|
|
|
|
"\tprevious declaration at %v", s, where, linestr(line2))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var vargen int
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// declare individual names - var, typ, const
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
var declare_typegen int
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// declare records that Node n declares symbol n.Sym in the specified
|
|
|
|
|
// declaration context.
|
2015-10-26 14:57:36 -07:00
|
|
|
func declare(n *Node, ctxt Class) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if ctxt == PDISCARD {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if isblank(n) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-26 23:08:39 -04:00
|
|
|
if n.Name == nil {
|
|
|
|
|
// named OLITERAL needs Name; most OLITERALs don't.
|
|
|
|
|
n.Name = new(Name)
|
|
|
|
|
}
|
2016-12-07 17:40:46 -08:00
|
|
|
n.Pos = lineno
|
2015-02-23 16:07:24 -05:00
|
|
|
s := n.Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-03-01 23:21:55 +00:00
|
|
|
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
2017-03-23 17:39:28 -07:00
|
|
|
if !inimport && !typecheckok && s.Pkg != localpkg {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("cannot declare name %v", s)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ctxt == PEXTERN && s.Name == "init" {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("cannot declare init - must be func")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
gen := 0
|
2015-02-13 14:40:36 -05:00
|
|
|
if ctxt == PEXTERN {
|
2015-09-10 15:57:39 +10:00
|
|
|
externdcl = append(externdcl, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
|
|
|
|
if Curfn == nil && ctxt == PAUTO {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("automatic outside function")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
if Curfn != nil {
|
2016-02-25 10:35:19 -08:00
|
|
|
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
if n.Op == OTYPE {
|
|
|
|
|
declare_typegen++
|
|
|
|
|
gen = declare_typegen
|
|
|
|
|
} else if n.Op == ONAME && ctxt == PAUTO && !strings.Contains(s.Name, "·") {
|
|
|
|
|
vargen++
|
|
|
|
|
gen = vargen
|
|
|
|
|
}
|
|
|
|
|
pushdcl(s)
|
2015-05-27 07:31:56 -04:00
|
|
|
n.Name.Curfn = Curfn
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ctxt == PAUTO {
|
|
|
|
|
n.Xoffset = 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if s.Block == block {
|
|
|
|
|
// functype will print errors about duplicate function arguments.
|
|
|
|
|
// Don't repeat the error here.
|
|
|
|
|
if ctxt != PPARAM && ctxt != PPARAMOUT {
|
|
|
|
|
redeclare(s, "in this block")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s.Block = block
|
2016-03-02 11:01:25 -08:00
|
|
|
s.Lastlineno = lineno
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
s.Def = asTypesNode(n)
|
2015-05-26 23:56:14 -04:00
|
|
|
n.Name.Vargen = int32(gen)
|
2016-09-16 00:33:29 +10:00
|
|
|
n.Name.Funcdepth = funcdepth
|
2015-10-26 14:57:36 -07:00
|
|
|
n.Class = ctxt
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
autoexport(n, ctxt)
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func addvar(n *Node, t *types.Type, ctxt Class) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n == nil || n.Sym == nil || (n.Op != ONAME && n.Op != ONONAME) || t == nil {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("addvar: n=%v t=%v nil", n, t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n.Op = ONAME
|
|
|
|
|
declare(n, ctxt)
|
|
|
|
|
n.Type = t
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// declare variables from grammar
|
|
|
|
|
// new_name_list (type | [type] = expr_list)
|
2016-03-09 20:29:21 -08:00
|
|
|
func variter(vl []*Node, t *Node, el []*Node) []*Node {
|
|
|
|
|
var init []*Node
|
|
|
|
|
doexpr := len(el) > 0
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-03-09 20:29:21 -08:00
|
|
|
if len(el) == 1 && len(vl) > 1 {
|
|
|
|
|
e := el[0]
|
2016-09-16 11:00:54 +10:00
|
|
|
as2 := nod(OAS2, nil, nil)
|
2016-03-09 20:29:21 -08:00
|
|
|
as2.List.Set(vl)
|
2016-03-10 10:13:42 -08:00
|
|
|
as2.Rlist.Set1(e)
|
2016-03-09 20:29:21 -08:00
|
|
|
for _, v := range vl {
|
2015-02-13 14:40:36 -05:00
|
|
|
v.Op = ONAME
|
|
|
|
|
declare(v, dclcontext)
|
2015-05-27 00:44:05 -04:00
|
|
|
v.Name.Param.Ntype = t
|
2015-05-26 22:19:27 -04:00
|
|
|
v.Name.Defn = as2
|
2016-09-16 00:33:29 +10:00
|
|
|
if funcdepth > 0 {
|
2016-09-16 11:00:54 +10:00
|
|
|
init = append(init, nod(ODCL, v, nil))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-09 20:29:21 -08:00
|
|
|
return append(init, as2)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-09 20:29:21 -08:00
|
|
|
for _, v := range vl {
|
|
|
|
|
var e *Node
|
2015-02-17 22:13:49 -05:00
|
|
|
if doexpr {
|
2016-03-09 20:29:21 -08:00
|
|
|
if len(el) == 0 {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("missing expression in var declaration")
|
2015-02-13 14:40:36 -05:00
|
|
|
break
|
|
|
|
|
}
|
2016-03-09 20:29:21 -08:00
|
|
|
e = el[0]
|
|
|
|
|
el = el[1:]
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v.Op = ONAME
|
|
|
|
|
declare(v, dclcontext)
|
2015-05-27 00:44:05 -04:00
|
|
|
v.Name.Param.Ntype = t
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-09-16 00:33:29 +10:00
|
|
|
if e != nil || funcdepth > 0 || isblank(v) {
|
|
|
|
|
if funcdepth > 0 {
|
2016-09-16 11:00:54 +10:00
|
|
|
init = append(init, nod(ODCL, v, nil))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-09-16 11:00:54 +10:00
|
|
|
e = nod(OAS, v, e)
|
2016-03-09 20:29:21 -08:00
|
|
|
init = append(init, e)
|
2015-02-13 14:40:36 -05:00
|
|
|
if e.Right != nil {
|
2015-05-26 22:19:27 -04:00
|
|
|
v.Name.Defn = e
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-09 20:29:21 -08:00
|
|
|
if len(el) != 0 {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("extra expression in var declaration")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
return init
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-27 20:15:29 -07:00
|
|
|
// newnoname returns a new ONONAME Node associated with symbol s.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func newnoname(s *types.Sym) *Node {
|
2016-10-27 20:15:29 -07:00
|
|
|
if s == nil {
|
|
|
|
|
Fatalf("newnoname nil")
|
|
|
|
|
}
|
|
|
|
|
n := nod(ONONAME, nil, nil)
|
|
|
|
|
n.Sym = s
|
2017-02-27 19:56:38 +02:00
|
|
|
n.SetAddable(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Xoffset = 0
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-10 21:37:13 -07:00
|
|
|
// newfuncname generates a new name node for a function or method.
|
|
|
|
|
// TODO(rsc): Use an ODCLFUNC node instead. See comment in CL 7360.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func newfuncname(s *types.Sym) *Node {
|
2015-03-10 21:37:13 -07:00
|
|
|
n := newname(s)
|
|
|
|
|
n.Func = new(Func)
|
2017-02-27 19:56:38 +02:00
|
|
|
n.Func.SetIsHiddenClosure(Curfn != nil)
|
2015-03-10 21:37:13 -07:00
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// this generates a new name node for a name
|
|
|
|
|
// being declared.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func dclname(s *types.Sym) *Node {
|
2015-02-23 16:07:24 -05:00
|
|
|
n := newname(s)
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Op = ONONAME // caller will correct it
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func typenod(t *types.Type) *Node {
|
2015-02-13 14:40:36 -05:00
|
|
|
// if we copied another type with *t = *u
|
|
|
|
|
// then t->nod might be out of date, so
|
|
|
|
|
// check t->nod->type too
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if asNode(t.Nod) == nil || asNode(t.Nod).Type != t {
|
|
|
|
|
t.Nod = asTypesNode(nod(OTYPE, nil, nil))
|
|
|
|
|
asNode(t.Nod).Type = t
|
|
|
|
|
asNode(t.Nod).Sym = t.Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
return asNode(t.Nod)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func anonfield(typ *types.Type) *Node {
|
2016-10-18 16:11:50 -07:00
|
|
|
return nod(ODCLFIELD, nil, typenod(typ))
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func namedfield(s string, typ *types.Type) *Node {
|
2016-10-18 16:11:50 -07:00
|
|
|
return nod(ODCLFIELD, newname(lookup(s)), typenod(typ))
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-05 12:48:49 -07:00
|
|
|
// oldname returns the Node that declares symbol s in the current scope.
|
|
|
|
|
// If no such Node currently exists, an ONONAME Node is returned instead.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func oldname(s *types.Sym) *Node {
|
|
|
|
|
n := asNode(s.Def)
|
2015-02-13 14:40:36 -05:00
|
|
|
if n == nil {
|
2016-04-05 12:48:49 -07:00
|
|
|
// Maybe a top-level declaration will come along later to
|
|
|
|
|
// define s. resolve will check s.Def again once all input
|
|
|
|
|
// source has been processed.
|
2016-10-31 16:20:42 -07:00
|
|
|
return newnoname(s)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-16 00:33:29 +10:00
|
|
|
if Curfn != nil && n.Op == ONAME && n.Name.Funcdepth > 0 && n.Name.Funcdepth != funcdepth {
|
2016-05-27 00:56:19 -04:00
|
|
|
// Inner func is referring to var in outer func.
|
2015-02-13 14:40:36 -05:00
|
|
|
//
|
|
|
|
|
// TODO(rsc): If there is an outer variable x and we
|
|
|
|
|
// are parsing x := 5 inside the closure, until we get to
|
|
|
|
|
// the := it looks like a reference to the outer x so we'll
|
|
|
|
|
// make x a closure variable unnecessarily.
|
2016-05-27 00:56:19 -04:00
|
|
|
c := n.Name.Param.Innermost
|
2016-09-16 00:33:29 +10:00
|
|
|
if c == nil || c.Name.Funcdepth != funcdepth {
|
2016-05-27 00:56:19 -04:00
|
|
|
// Do not have a closure var for the active closure yet; make one.
|
2017-03-24 15:57:12 -07:00
|
|
|
c = newname(s)
|
2016-05-25 10:29:50 -04:00
|
|
|
c.Class = PAUTOHEAP
|
2017-02-27 19:56:38 +02:00
|
|
|
c.SetIsClosureVar(true)
|
|
|
|
|
c.SetIsddd(n.Isddd())
|
2015-05-26 22:19:27 -04:00
|
|
|
c.Name.Defn = n
|
2017-02-27 19:56:38 +02:00
|
|
|
c.SetAddable(false)
|
2016-09-16 00:33:29 +10:00
|
|
|
c.Name.Funcdepth = funcdepth
|
2016-05-27 14:24:26 -04:00
|
|
|
|
2016-05-27 00:56:19 -04:00
|
|
|
// Link into list of active closure variables.
|
|
|
|
|
// Popped from list in func closurebody.
|
|
|
|
|
c.Name.Param.Outer = n.Name.Param.Innermost
|
|
|
|
|
n.Name.Param.Innermost = c
|
|
|
|
|
|
2016-02-26 17:03:58 -08:00
|
|
|
Curfn.Func.Cvars.Append(c)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// return ref to closure var, not original
|
2016-05-27 00:56:19 -04:00
|
|
|
return c
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// := declarations
|
2015-02-17 22:13:49 -05:00
|
|
|
func colasname(n *Node) bool {
|
2015-02-13 14:40:36 -05:00
|
|
|
switch n.Op {
|
|
|
|
|
case ONAME,
|
|
|
|
|
ONONAME,
|
|
|
|
|
OPACK,
|
|
|
|
|
OTYPE,
|
|
|
|
|
OLITERAL:
|
2015-02-17 22:13:49 -05:00
|
|
|
return n.Sym != nil
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-17 22:13:49 -05:00
|
|
|
return false
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-25 15:34:55 -07:00
|
|
|
func colasdefn(left []*Node, defn *Node) {
|
|
|
|
|
for _, n := range left {
|
|
|
|
|
if n.Sym != nil {
|
2017-03-06 20:00:54 +02:00
|
|
|
n.Sym.SetUniq(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-25 15:34:55 -07:00
|
|
|
var nnew, nerr int
|
|
|
|
|
for i, n := range left {
|
2015-02-13 14:40:36 -05:00
|
|
|
if isblank(n) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2015-02-17 22:13:49 -05:00
|
|
|
if !colasname(n) {
|
2016-12-07 17:40:46 -08:00
|
|
|
yyerrorl(defn.Pos, "non-name %v on left side of :=", n)
|
2015-02-13 14:40:36 -05:00
|
|
|
nerr++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-06 20:00:54 +02:00
|
|
|
if !n.Sym.Uniq() {
|
2016-12-07 17:40:46 -08:00
|
|
|
yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym)
|
2017-02-27 19:56:38 +02:00
|
|
|
n.SetDiag(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
nerr++
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-06 20:00:54 +02:00
|
|
|
n.Sym.SetUniq(false)
|
2015-02-13 14:40:36 -05:00
|
|
|
if n.Sym.Block == block {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nnew++
|
|
|
|
|
n = newname(n.Sym)
|
|
|
|
|
declare(n, dclcontext)
|
2015-05-26 22:19:27 -04:00
|
|
|
n.Name.Defn = defn
|
2016-09-16 11:00:54 +10:00
|
|
|
defn.Ninit.Append(nod(ODCL, n, nil))
|
2016-03-25 15:34:55 -07:00
|
|
|
left[i] = n
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if nnew == 0 && nerr == 0 {
|
2016-12-07 17:40:46 -08:00
|
|
|
yyerrorl(defn.Pos, "no new variables on left side of :=")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// declare the arguments in an
|
|
|
|
|
// interface field declaration.
|
2015-02-13 14:40:36 -05:00
|
|
|
func ifacedcl(n *Node) {
|
|
|
|
|
if n.Op != ODCLFIELD || n.Right == nil {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("ifacedcl")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if isblank(n.Left) {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("methods must have a unique non-blank name")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// declare the function proper
|
|
|
|
|
// and declare the arguments.
|
|
|
|
|
// called in extern-declaration context
|
|
|
|
|
// returns in auto-declaration context.
|
2017-04-07 19:50:31 +00:00
|
|
|
func funchdr(n *Node) {
|
2015-02-13 14:40:36 -05:00
|
|
|
// change the declaration context from extern to auto
|
2016-09-16 00:33:29 +10:00
|
|
|
if funcdepth == 0 && dclcontext != PEXTERN {
|
2016-03-18 17:21:32 -07:00
|
|
|
Fatalf("funchdr: dclcontext = %d", dclcontext)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dclcontext = PAUTO
|
2017-04-07 19:50:31 +00:00
|
|
|
funcstart(n)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-05-27 10:42:55 -04:00
|
|
|
if n.Func.Nname != nil {
|
|
|
|
|
funcargs(n.Func.Nname.Name.Param.Ntype)
|
2015-05-27 00:44:05 -04:00
|
|
|
} else if n.Func.Ntype != nil {
|
|
|
|
|
funcargs(n.Func.Ntype)
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
|
|
|
|
funcargs2(n.Type)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func funcargs(nt *Node) {
|
|
|
|
|
if nt.Op != OTFUNC {
|
2016-04-27 15:10:10 +10:00
|
|
|
Fatalf("funcargs %v", nt.Op)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// re-start the variable generation number
|
|
|
|
|
// we want to use small numbers for the return variables,
|
|
|
|
|
// so let them have the chunk starting at 1.
|
2016-03-08 15:10:26 -08:00
|
|
|
vargen = nt.Rlist.Len()
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
// declare the receiver and in arguments.
|
|
|
|
|
// no n->defn because type checking of func header
|
|
|
|
|
// will not fill in the types until later
|
|
|
|
|
if nt.Left != nil {
|
2015-02-23 16:07:24 -05:00
|
|
|
n := nt.Left
|
2015-02-13 14:40:36 -05:00
|
|
|
if n.Op != ODCLFIELD {
|
2016-04-27 15:10:10 +10:00
|
|
|
Fatalf("funcargs receiver %v", n.Op)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
if n.Left != nil {
|
|
|
|
|
n.Left.Op = ONAME
|
2015-05-27 00:44:05 -04:00
|
|
|
n.Left.Name.Param.Ntype = n.Right
|
2015-02-13 14:40:36 -05:00
|
|
|
declare(n.Left, PPARAM)
|
|
|
|
|
if dclcontext == PAUTO {
|
|
|
|
|
vargen++
|
2015-05-26 23:56:14 -04:00
|
|
|
n.Left.Name.Vargen = int32(vargen)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-31 11:58:19 +11:00
|
|
|
for _, n := range nt.List.Slice() {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n.Op != ODCLFIELD {
|
2016-04-27 15:10:10 +10:00
|
|
|
Fatalf("funcargs in %v", n.Op)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
if n.Left != nil {
|
|
|
|
|
n.Left.Op = ONAME
|
2015-05-27 00:44:05 -04:00
|
|
|
n.Left.Name.Param.Ntype = n.Right
|
2015-02-13 14:40:36 -05:00
|
|
|
declare(n.Left, PPARAM)
|
|
|
|
|
if dclcontext == PAUTO {
|
|
|
|
|
vargen++
|
2015-05-26 23:56:14 -04:00
|
|
|
n.Left.Name.Vargen = int32(vargen)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// declare the out arguments.
|
2016-03-08 15:10:26 -08:00
|
|
|
gen := nt.List.Len()
|
2015-02-13 14:40:36 -05:00
|
|
|
var i int = 0
|
2016-03-31 11:58:19 +11:00
|
|
|
for _, n := range nt.Rlist.Slice() {
|
2015-02-13 14:40:36 -05:00
|
|
|
if n.Op != ODCLFIELD {
|
2016-04-27 15:10:10 +10:00
|
|
|
Fatalf("funcargs out %v", n.Op)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if n.Left == nil {
|
|
|
|
|
// Name so that escape analysis can track it. ~r stands for 'result'.
|
2016-09-15 15:45:10 +10:00
|
|
|
n.Left = newname(lookupN("~r", gen))
|
2015-02-13 14:40:36 -05:00
|
|
|
gen++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: n->left->missing = 1;
|
|
|
|
|
n.Left.Op = ONAME
|
|
|
|
|
|
|
|
|
|
if isblank(n.Left) {
|
|
|
|
|
// Give it a name so we can assign to it during return. ~b stands for 'blank'.
|
|
|
|
|
// The name must be different from ~r above because if you have
|
|
|
|
|
// func f() (_ int)
|
|
|
|
|
// func g() int
|
|
|
|
|
// f is allowed to use a plain 'return' with no arguments, while g is not.
|
|
|
|
|
// So the two cases must be distinguished.
|
|
|
|
|
// We do not record a pointer to the original node (n->orig).
|
|
|
|
|
// Having multiple names causes too much confusion in later passes.
|
2016-03-23 16:01:15 +11:00
|
|
|
nn := *n.Left
|
|
|
|
|
nn.Orig = &nn
|
2016-09-15 15:45:10 +10:00
|
|
|
nn.Sym = lookupN("~b", gen)
|
2015-02-13 14:40:36 -05:00
|
|
|
gen++
|
2016-03-23 16:01:15 +11:00
|
|
|
n.Left = &nn
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-05-27 00:44:05 -04:00
|
|
|
n.Left.Name.Param.Ntype = n.Right
|
2015-02-13 14:40:36 -05:00
|
|
|
declare(n.Left, PPARAMOUT)
|
|
|
|
|
if dclcontext == PAUTO {
|
|
|
|
|
i++
|
2015-05-26 23:56:14 -04:00
|
|
|
n.Left.Name.Vargen = int32(i)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// Same as funcargs, except run over an already constructed TFUNC.
|
|
|
|
|
// This happens during import, where the hidden_fndcl rule has
|
|
|
|
|
// used functype directly to parse the function's type.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func funcargs2(t *types.Type) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if t.Etype != TFUNC {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("funcargs2 %v", t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-17 01:47:16 -07:00
|
|
|
for _, ft := range t.Recvs().Fields().Slice() {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil {
|
2016-03-17 01:47:16 -07:00
|
|
|
continue
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
n := asNode(ft.Nname) // no need for newname(ft->nname->sym)
|
2016-03-17 01:47:16 -07:00
|
|
|
n.Type = ft.Type
|
|
|
|
|
declare(n, PPARAM)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-17 01:47:16 -07:00
|
|
|
for _, ft := range t.Params().Fields().Slice() {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil {
|
2016-03-17 01:47:16 -07:00
|
|
|
continue
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
n := asNode(ft.Nname)
|
2016-03-17 01:47:16 -07:00
|
|
|
n.Type = ft.Type
|
|
|
|
|
declare(n, PPARAM)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-17 01:47:16 -07:00
|
|
|
for _, ft := range t.Results().Fields().Slice() {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if asNode(ft.Nname) == nil || asNode(ft.Nname).Sym == nil {
|
2016-03-17 01:47:16 -07:00
|
|
|
continue
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
n := asNode(ft.Nname)
|
2016-03-17 01:47:16 -07:00
|
|
|
n.Type = ft.Type
|
|
|
|
|
declare(n, PPARAMOUT)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-05-26 23:43:19 -04:00
|
|
|
var funcstack []*Node // stack of previous values of Curfn
|
2016-09-16 00:33:29 +10:00
|
|
|
var funcdepth int32 // len(funcstack) during parsing, but then forced to be the same later during compilation
|
2016-05-26 23:43:19 -04:00
|
|
|
|
|
|
|
|
// start the function.
|
|
|
|
|
// called before funcargs; undone at end of funcbody.
|
2017-04-07 19:50:31 +00:00
|
|
|
func funcstart(n *Node) {
|
|
|
|
|
markdcl()
|
2016-05-26 23:43:19 -04:00
|
|
|
funcstack = append(funcstack, Curfn)
|
2016-09-16 00:33:29 +10:00
|
|
|
funcdepth++
|
2016-05-26 23:43:19 -04:00
|
|
|
Curfn = n
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// finish the body.
|
|
|
|
|
// called in auto-declaration context.
|
|
|
|
|
// returns in extern-declaration context.
|
2017-04-07 19:50:31 +00:00
|
|
|
func funcbody(n *Node) {
|
2015-02-13 14:40:36 -05:00
|
|
|
// change the declaration context from auto to extern
|
|
|
|
|
if dclcontext != PAUTO {
|
2016-03-18 17:21:32 -07:00
|
|
|
Fatalf("funcbody: unexpected dclcontext %d", dclcontext)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2017-04-07 19:50:31 +00:00
|
|
|
popdcl()
|
2016-05-26 23:43:19 -04:00
|
|
|
funcstack, Curfn = funcstack[:len(funcstack)-1], funcstack[len(funcstack)-1]
|
2016-09-16 00:33:29 +10:00
|
|
|
funcdepth--
|
|
|
|
|
if funcdepth == 0 {
|
2015-02-13 14:40:36 -05:00
|
|
|
dclcontext = PEXTERN
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// structs, functions, and methods.
|
|
|
|
|
// they don't belong here, but where do they belong?
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func checkembeddedtype(t *types.Type) {
|
2015-02-13 14:40:36 -05:00
|
|
|
if t == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-30 15:09:25 -07:00
|
|
|
if t.Sym == nil && t.IsPtr() {
|
2016-03-30 10:57:47 -07:00
|
|
|
t = t.Elem()
|
2016-03-30 14:56:08 -07:00
|
|
|
if t.IsInterface() {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("embedded type cannot be a pointer to interface")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-20 14:05:48 -07:00
|
|
|
if t.IsPtr() || t.IsUnsafePtr() {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("embedded type cannot be a pointer")
|
2016-12-07 16:02:42 -08:00
|
|
|
} else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
|
2016-04-01 20:11:30 -07:00
|
|
|
t.ForwardType().Embedlineno = lineno
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func structfield(n *Node) *types.Field {
|
2016-03-02 17:34:42 -08:00
|
|
|
lno := lineno
|
2016-12-07 17:40:46 -08:00
|
|
|
lineno = n.Pos
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if n.Op != ODCLFIELD {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("structfield: oops %v\n", n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f := types.NewField()
|
2017-02-27 19:56:38 +02:00
|
|
|
f.SetIsddd(n.Isddd())
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if n.Right != nil {
|
cmd/compile: reduce use of **Node parameters
Escape analysis has a hard time with tree-like
structures (see #13493 and #14858).
This is unlikely to change.
As a result, when invoking a function that accepts
a **Node parameter, we usually allocate a *Node
on the heap. This happens a whole lot.
This CL changes functions from taking a **Node
to acting more like append: It both modifies
the input and returns a replacement for it.
Because of the cascading nature of escape analysis,
in order to get the benefits, I had to modify
almost all such functions. The remaining functions
are in racewalk and the backend. I would be happy
to update them as well in a separate CL.
This CL was created by manually updating the
function signatures and the directly impacted
bits of code. The callsites were then automatically
updated using a bespoke script:
https://gist.github.com/josharian/046b1be7aceae244de39
For ease of reviewing and future understanding,
this CL is also broken down into four CLs,
mailed separately, which show the manual
and the automated changes separately.
They are CLs 20990, 20991, 20992, and 20993.
Passes toolstash -cmp.
name old time/op new time/op delta
Template 335ms ± 5% 324ms ± 5% -3.35% (p=0.000 n=23+24)
Unicode 176ms ± 9% 165ms ± 6% -6.12% (p=0.000 n=23+24)
GoTypes 1.10s ± 4% 1.07s ± 2% -2.77% (p=0.000 n=24+24)
Compiler 5.31s ± 3% 5.15s ± 3% -2.95% (p=0.000 n=24+24)
MakeBash 41.6s ± 1% 41.7s ± 2% ~ (p=0.586 n=23+23)
name old alloc/op new alloc/op delta
Template 63.3MB ± 0% 62.4MB ± 0% -1.36% (p=0.000 n=25+23)
Unicode 42.4MB ± 0% 41.6MB ± 0% -1.99% (p=0.000 n=24+25)
GoTypes 220MB ± 0% 217MB ± 0% -1.11% (p=0.000 n=25+25)
Compiler 994MB ± 0% 973MB ± 0% -2.08% (p=0.000 n=24+25)
name old allocs/op new allocs/op delta
Template 681k ± 0% 574k ± 0% -15.71% (p=0.000 n=24+25)
Unicode 518k ± 0% 413k ± 0% -20.34% (p=0.000 n=25+24)
GoTypes 2.08M ± 0% 1.78M ± 0% -14.62% (p=0.000 n=25+25)
Compiler 9.26M ± 0% 7.64M ± 0% -17.48% (p=0.000 n=25+25)
name old text-bytes new text-bytes delta
HelloSize 578k ± 0% 578k ± 0% ~ (all samples are equal)
CmdGoSize 6.46M ± 0% 6.46M ± 0% ~ (all samples are equal)
name old data-bytes new data-bytes delta
HelloSize 128k ± 0% 128k ± 0% ~ (all samples are equal)
CmdGoSize 281k ± 0% 281k ± 0% ~ (all samples are equal)
name old exe-bytes new exe-bytes delta
HelloSize 921k ± 0% 921k ± 0% ~ (all samples are equal)
CmdGoSize 9.86M ± 0% 9.86M ± 0% ~ (all samples are equal)
Change-Id: I277d95bd56d51c166ef7f560647aeaa092f3f475
Reviewed-on: https://go-review.googlesource.com/20959
Reviewed-by: Dave Cheney <dave@cheney.net>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-03-20 08:03:31 -07:00
|
|
|
n.Right = typecheck(n.Right, Etype)
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Type = n.Right.Type
|
|
|
|
|
if n.Left != nil {
|
|
|
|
|
n.Left.Type = n.Type
|
|
|
|
|
}
|
|
|
|
|
if n.Embedded != 0 {
|
|
|
|
|
checkembeddedtype(n.Type)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n.Right = nil
|
|
|
|
|
|
|
|
|
|
f.Type = n.Type
|
|
|
|
|
if f.Type == nil {
|
2017-02-27 19:56:38 +02:00
|
|
|
f.SetBroke(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-22 12:27:29 -07:00
|
|
|
switch u := n.Val().U.(type) {
|
|
|
|
|
case string:
|
2016-04-25 13:24:48 -07:00
|
|
|
f.Note = u
|
2015-02-13 14:40:36 -05:00
|
|
|
default:
|
2017-03-24 11:43:08 -07:00
|
|
|
yyerror("field tag must be a string")
|
2016-04-22 12:27:29 -07:00
|
|
|
case nil:
|
2017-03-24 11:43:08 -07:00
|
|
|
// no-op
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if n.Left != nil && n.Left.Op == ONAME {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f.Nname = asTypesNode(n.Left)
|
2015-02-13 14:40:36 -05:00
|
|
|
f.Embedded = n.Embedded
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f.Sym = asNode(f.Nname).Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-02 17:34:42 -08:00
|
|
|
lineno = lno
|
2015-02-13 14:40:36 -05:00
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-10 15:50:49 -08:00
|
|
|
// checkdupfields emits errors for duplicately named fields or methods in
|
|
|
|
|
// a list of struct or interface types.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func checkdupfields(what string, ts ...*types.Type) {
|
|
|
|
|
seen := make(map[*types.Sym]bool)
|
2016-03-10 15:50:49 -08:00
|
|
|
for _, t := range ts {
|
2016-03-17 01:32:18 -07:00
|
|
|
for _, f := range t.Fields().Slice() {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if f.Sym == nil || isblanksym(f.Sym) || asNode(f.Nname) == nil {
|
2016-03-10 15:50:49 -08:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if seen[f.Sym] {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
yyerrorl(asNode(f.Nname).Pos, "duplicate %s %s", what, f.Sym.Name)
|
2016-03-10 15:50:49 -08:00
|
|
|
continue
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-10 15:50:49 -08:00
|
|
|
seen[f.Sym] = true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// convert a parsed id/type list into
|
|
|
|
|
// a type for struct/interface/arglist
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func tostruct(l []*Node) *types.Type {
|
|
|
|
|
t := types.New(TSTRUCT)
|
2015-08-13 19:05:37 -07:00
|
|
|
tostruct0(t, l)
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func tostruct0(t *types.Type, l []*Node) {
|
2016-03-30 14:56:08 -07:00
|
|
|
if t == nil || !t.IsStruct() {
|
2015-08-13 19:05:37 -07:00
|
|
|
Fatalf("struct expected")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
fields := make([]*types.Field, len(l))
|
2016-03-31 11:58:19 +11:00
|
|
|
for i, n := range l {
|
2016-03-31 10:30:04 +11:00
|
|
|
f := structfield(n)
|
2017-02-27 19:56:38 +02:00
|
|
|
if f.Broke() {
|
|
|
|
|
t.SetBroke(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-31 11:58:19 +11:00
|
|
|
fields[i] = f
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-31 10:30:04 +11:00
|
|
|
t.SetFields(fields)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-03-10 15:50:49 -08:00
|
|
|
checkdupfields("field", t)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2017-02-27 19:56:38 +02:00
|
|
|
if !t.Broke() {
|
2015-02-13 14:40:36 -05:00
|
|
|
checkwidth(t)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func tofunargs(l []*Node, funarg types.Funarg) *types.Type {
|
|
|
|
|
t := types.New(TSTRUCT)
|
2016-05-25 10:01:58 -04:00
|
|
|
t.StructType().Funarg = funarg
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
fields := make([]*types.Field, len(l))
|
2016-03-31 11:58:19 +11:00
|
|
|
for i, n := range l {
|
2016-03-10 05:22:14 -08:00
|
|
|
f := structfield(n)
|
2016-05-25 10:01:58 -04:00
|
|
|
f.Funarg = funarg
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// esc.go needs to find f given a PPARAM to add the tag.
|
2016-03-09 12:39:36 -08:00
|
|
|
if n.Left != nil && n.Left.Class == PPARAM {
|
|
|
|
|
n.Left.Name.Param.Field = f
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2017-02-27 19:56:38 +02:00
|
|
|
if f.Broke() {
|
|
|
|
|
t.SetBroke(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-31 11:58:19 +11:00
|
|
|
fields[i] = f
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-03-31 10:30:04 +11:00
|
|
|
t.SetFields(fields)
|
2015-02-13 14:40:36 -05:00
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func tofunargsfield(fields []*types.Field, funarg types.Funarg) *types.Type {
|
|
|
|
|
t := types.New(TSTRUCT)
|
2016-10-20 17:33:45 -07:00
|
|
|
t.StructType().Funarg = funarg
|
|
|
|
|
|
|
|
|
|
for _, f := range fields {
|
|
|
|
|
f.Funarg = funarg
|
|
|
|
|
|
|
|
|
|
// esc.go needs to find f given a PPARAM to add the tag.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if asNode(f.Nname) != nil && asNode(f.Nname).Class == PPARAM {
|
|
|
|
|
asNode(f.Nname).Name.Param.Field = f
|
2016-10-20 17:33:45 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
t.SetFields(fields)
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func interfacefield(n *Node) *types.Field {
|
2016-03-02 17:34:42 -08:00
|
|
|
lno := lineno
|
2016-12-07 17:40:46 -08:00
|
|
|
lineno = n.Pos
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if n.Op != ODCLFIELD {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("interfacefield: oops %v\n", n)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-05-27 00:47:05 -04:00
|
|
|
if n.Val().Ctype() != CTxxx {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("interface method cannot have annotation")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2017-03-20 11:56:15 -07:00
|
|
|
// MethodSpec = MethodName Signature | InterfaceTypeName .
|
|
|
|
|
//
|
|
|
|
|
// If Left != nil, then Left is MethodName and Right is Signature.
|
|
|
|
|
// Otherwise, Right is InterfaceTypeName.
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if n.Right != nil {
|
2017-03-20 11:56:15 -07:00
|
|
|
n.Right = typecheck(n.Right, Etype)
|
|
|
|
|
n.Type = n.Right.Type
|
|
|
|
|
n.Right = nil
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f := types.NewField()
|
2017-03-20 11:56:15 -07:00
|
|
|
if n.Left != nil {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f.Nname = asTypesNode(n.Left)
|
|
|
|
|
f.Sym = asNode(f.Nname).Sym
|
2017-03-20 11:56:15 -07:00
|
|
|
} else {
|
|
|
|
|
// Placeholder ONAME just to hold Pos.
|
|
|
|
|
// TODO(mdempsky): Add Pos directly to Field instead.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f.Nname = asTypesNode(newname(nblank.Sym))
|
2017-03-20 11:56:15 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
f.Type = n.Type
|
|
|
|
|
if f.Type == nil {
|
2017-02-27 19:56:38 +02:00
|
|
|
f.SetBroke(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-02 17:34:42 -08:00
|
|
|
lineno = lno
|
2015-02-13 14:40:36 -05:00
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func tointerface(l []*Node) *types.Type {
|
2017-03-18 14:39:48 -07:00
|
|
|
if len(l) == 0 {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
return types.Types[TINTER]
|
2017-03-18 14:39:48 -07:00
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
t := types.New(TINTER)
|
2015-08-13 19:05:37 -07:00
|
|
|
tointerface0(t, l)
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func tointerface0(t *types.Type, l []*Node) *types.Type {
|
2016-03-30 14:56:08 -07:00
|
|
|
if t == nil || !t.IsInterface() {
|
2015-08-13 19:05:37 -07:00
|
|
|
Fatalf("interface expected")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
var fields []*types.Field
|
2016-03-08 15:10:26 -08:00
|
|
|
for _, n := range l {
|
|
|
|
|
f := interfacefield(n)
|
2017-02-27 19:56:38 +02:00
|
|
|
if f.Broke() {
|
|
|
|
|
t.SetBroke(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2017-03-20 11:56:15 -07:00
|
|
|
fields = append(fields, f)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2017-03-20 02:32:42 -07:00
|
|
|
t.SetInterface(fields)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func embedded(s *types.Sym, pkg *types.Pkg) *Node {
|
2015-02-13 14:40:36 -05:00
|
|
|
const (
|
|
|
|
|
CenterDot = 0xB7
|
|
|
|
|
)
|
|
|
|
|
// Names sometimes have disambiguation junk
|
2016-03-01 23:21:55 +00:00
|
|
|
// appended after a center dot. Discard it when
|
2015-02-13 14:40:36 -05:00
|
|
|
// making the name for the embedded struct field.
|
2015-02-23 16:07:24 -05:00
|
|
|
name := s.Name
|
2015-02-13 14:40:36 -05:00
|
|
|
|
|
|
|
|
if i := strings.Index(s.Name, string(CenterDot)); i >= 0 {
|
|
|
|
|
name = s.Name[:i]
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
var n *Node
|
2015-02-13 14:40:36 -05:00
|
|
|
if exportname(name) {
|
2016-09-15 15:45:10 +10:00
|
|
|
n = newname(lookup(name))
|
2015-02-13 14:40:36 -05:00
|
|
|
} else if s.Pkg == builtinpkg {
|
|
|
|
|
// The name of embedded builtins belongs to pkg.
|
2017-03-30 13:19:18 -07:00
|
|
|
n = newname(pkg.Lookup(name))
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
2017-03-30 13:19:18 -07:00
|
|
|
n = newname(s.Pkg.Lookup(name))
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
2016-09-16 11:00:54 +10:00
|
|
|
n = nod(ODCLFIELD, n, oldname(s))
|
2015-02-13 14:40:36 -05:00
|
|
|
n.Embedded = 1
|
|
|
|
|
return n
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-25 16:25:57 -07:00
|
|
|
// thisT is the singleton type used for interface method receivers.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
var thisT *types.Type
|
2016-10-25 16:25:57 -07:00
|
|
|
|
2015-02-13 14:40:36 -05:00
|
|
|
func fakethis() *Node {
|
2016-10-25 16:25:57 -07:00
|
|
|
if thisT == nil {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
thisT = types.NewPtr(types.New(TSTRUCT))
|
2016-10-25 16:25:57 -07:00
|
|
|
}
|
2017-03-28 15:13:19 -07:00
|
|
|
return anonfield(thisT)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func fakethisfield() *types.Field {
|
2016-10-25 16:25:57 -07:00
|
|
|
if thisT == nil {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
thisT = types.NewPtr(types.New(TSTRUCT))
|
2016-10-25 16:25:57 -07:00
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f := types.NewField()
|
2016-10-25 16:25:57 -07:00
|
|
|
f.Type = thisT
|
2016-10-20 17:33:45 -07:00
|
|
|
return f
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// Is this field a method on an interface?
|
2016-10-25 16:25:57 -07:00
|
|
|
// Those methods have thisT as the receiver.
|
2015-10-22 09:51:12 +09:00
|
|
|
// (See fakethis above.)
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func isifacemethod(f *types.Type) bool {
|
2016-10-25 16:25:57 -07:00
|
|
|
return f.Recv().Type == thisT
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-10-22 09:51:12 +09:00
|
|
|
// turn a parsed function declaration into a type
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func functype(this *Node, in, out []*Node) *types.Type {
|
|
|
|
|
t := types.New(TFUNC)
|
2015-08-13 19:05:37 -07:00
|
|
|
functype0(t, this, in, out)
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func functype0(t *types.Type, this *Node, in, out []*Node) {
|
2015-08-13 19:05:37 -07:00
|
|
|
if t == nil || t.Etype != TFUNC {
|
|
|
|
|
Fatalf("function type expected")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-03-08 10:26:20 -08:00
|
|
|
var rcvr []*Node
|
2015-02-13 14:40:36 -05:00
|
|
|
if this != nil {
|
2016-03-08 10:26:20 -08:00
|
|
|
rcvr = []*Node{this}
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
t.FuncType().Receiver = tofunargs(rcvr, types.FunargRcvr)
|
|
|
|
|
t.FuncType().Results = tofunargs(out, types.FunargResults)
|
|
|
|
|
t.FuncType().Params = tofunargs(in, types.FunargParams)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-03-10 15:50:49 -08:00
|
|
|
checkdupfields("argument", t.Recvs(), t.Results(), t.Params())
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2017-02-27 19:56:38 +02:00
|
|
|
if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() {
|
|
|
|
|
t.SetBroke(true)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-04-01 20:11:30 -07:00
|
|
|
t.FuncType().Outnamed = false
|
2016-03-17 01:47:16 -07:00
|
|
|
if len(out) > 0 && out[0].Left != nil && out[0].Left.Orig != nil {
|
2016-03-09 20:29:21 -08:00
|
|
|
s := out[0].Left.Orig.Sym
|
2015-02-13 14:40:36 -05:00
|
|
|
if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
|
2016-04-01 20:11:30 -07:00
|
|
|
t.FuncType().Outnamed = true
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func functypefield(this *types.Field, in, out []*types.Field) *types.Type {
|
|
|
|
|
t := types.New(TFUNC)
|
2016-10-20 17:33:45 -07:00
|
|
|
functypefield0(t, this, in, out)
|
|
|
|
|
return t
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func functypefield0(t *types.Type, this *types.Field, in, out []*types.Field) {
|
|
|
|
|
var rcvr []*types.Field
|
2016-10-20 17:33:45 -07:00
|
|
|
if this != nil {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
rcvr = []*types.Field{this}
|
2016-10-20 17:33:45 -07:00
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
t.FuncType().Receiver = tofunargsfield(rcvr, types.FunargRcvr)
|
|
|
|
|
t.FuncType().Results = tofunargsfield(out, types.FunargRcvr)
|
|
|
|
|
t.FuncType().Params = tofunargsfield(in, types.FunargRcvr)
|
2016-10-20 17:33:45 -07:00
|
|
|
|
|
|
|
|
t.FuncType().Outnamed = false
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if len(out) > 0 && asNode(out[0].Nname) != nil && asNode(out[0].Nname).Orig != nil {
|
|
|
|
|
s := asNode(out[0].Nname).Orig.Sym
|
2016-10-20 17:33:45 -07:00
|
|
|
if s != nil && (s.Name[0] != '~' || s.Name[1] != 'r') { // ~r%d is the name invented for an unnamed result
|
|
|
|
|
t.FuncType().Outnamed = true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
var methodsym_toppkg *types.Pkg
|
2015-02-13 14:40:36 -05:00
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func methodsym(nsym *types.Sym, t0 *types.Type, iface bool) *types.Sym {
|
2017-03-31 09:57:38 -07:00
|
|
|
if t0 == nil {
|
|
|
|
|
Fatalf("methodsym: nil receiver type")
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
t := t0
|
2017-03-31 09:57:38 -07:00
|
|
|
s := t.Sym
|
2016-03-30 15:09:25 -07:00
|
|
|
if s == nil && t.IsPtr() {
|
2016-03-30 10:57:47 -07:00
|
|
|
t = t.Elem()
|
2015-02-13 14:40:36 -05:00
|
|
|
if t == nil {
|
2017-03-31 09:57:38 -07:00
|
|
|
Fatalf("methodsym: ptrto nil")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
s = t.Sym
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if t0 == *t and t0 has a sym,
|
|
|
|
|
// we want to see *t, not t0, in the method name.
|
|
|
|
|
if t != t0 && t0.Sym != nil {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
t0 = types.NewPtr(t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2017-03-31 09:57:38 -07:00
|
|
|
suffix := ""
|
|
|
|
|
if iface {
|
2015-02-13 14:40:36 -05:00
|
|
|
dowidth(t0)
|
2017-03-23 11:21:42 -07:00
|
|
|
if t0.Width < int64(Widthptr) {
|
2015-02-13 14:40:36 -05:00
|
|
|
suffix = "·i"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
var spkg *types.Pkg
|
2017-03-31 09:57:38 -07:00
|
|
|
if s != nil {
|
|
|
|
|
spkg = s.Pkg
|
|
|
|
|
}
|
|
|
|
|
pkgprefix := ""
|
2015-02-13 14:40:36 -05:00
|
|
|
if (spkg == nil || nsym.Pkg != spkg) && !exportname(nsym.Name) {
|
2017-03-31 09:57:38 -07:00
|
|
|
pkgprefix = "." + nsym.Pkg.Prefix
|
|
|
|
|
}
|
|
|
|
|
var p string
|
|
|
|
|
if t0.Sym == nil && t0.IsPtr() {
|
|
|
|
|
p = fmt.Sprintf("(%-S)%s.%s%s", t0, pkgprefix, nsym.Name, suffix)
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
2017-03-31 09:57:38 -07:00
|
|
|
p = fmt.Sprintf("%-S%s.%s%s", t0, pkgprefix, nsym.Name, suffix)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if spkg == nil {
|
|
|
|
|
if methodsym_toppkg == nil {
|
2015-03-02 16:03:26 -05:00
|
|
|
methodsym_toppkg = mkpkg("go")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
spkg = methodsym_toppkg
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-31 09:57:38 -07:00
|
|
|
return spkg.Lookup(p)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2017-01-23 14:24:24 -08:00
|
|
|
// methodname is a misnomer because this now returns a Sym, rather
|
|
|
|
|
// than an ONAME.
|
|
|
|
|
// TODO(mdempsky): Reconcile with methodsym.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func methodname(s *types.Sym, recv *types.Type) *types.Sym {
|
2016-10-20 17:33:45 -07:00
|
|
|
star := false
|
2017-01-23 14:24:24 -08:00
|
|
|
if recv.IsPtr() {
|
2016-10-20 17:33:45 -07:00
|
|
|
star = true
|
2017-01-23 14:24:24 -08:00
|
|
|
recv = recv.Elem()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2017-01-23 14:24:24 -08:00
|
|
|
tsym := recv.Sym
|
2016-10-20 17:33:45 -07:00
|
|
|
if tsym == nil || isblanksym(s) {
|
2017-01-23 14:24:24 -08:00
|
|
|
return s
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2015-02-23 16:07:24 -05:00
|
|
|
var p string
|
2016-10-20 17:33:45 -07:00
|
|
|
if star {
|
2017-03-08 17:08:31 -05:00
|
|
|
p = fmt.Sprintf("(*%v).%v", tsym.Name, s)
|
2015-02-13 14:40:36 -05:00
|
|
|
} else {
|
2016-10-20 17:33:45 -07:00
|
|
|
p = fmt.Sprintf("%v.%v", tsym, s)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2017-03-30 13:19:18 -07:00
|
|
|
s = tsym.Pkg.Lookup(p)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2017-01-23 14:24:24 -08:00
|
|
|
return s
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-11 17:12:31 -08:00
|
|
|
// Add a method, declared as a function.
|
|
|
|
|
// - msym is the method symbol
|
|
|
|
|
// - t is function type (with receiver)
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) {
|
2016-03-11 17:12:31 -08:00
|
|
|
if msym == nil {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("no method symbol")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// get parent type sym
|
2016-03-14 01:20:49 -07:00
|
|
|
rf := t.Recv() // ptr to this structure
|
|
|
|
|
if rf == nil {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("missing receiver")
|
2015-02-13 14:40:36 -05:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 13:50:03 -07:00
|
|
|
mt := methtype(rf.Type)
|
2016-08-30 13:43:37 -07:00
|
|
|
if mt == nil || mt.Sym == nil {
|
2016-08-30 13:50:03 -07:00
|
|
|
pa := rf.Type
|
|
|
|
|
t := pa
|
|
|
|
|
if t != nil && t.IsPtr() {
|
|
|
|
|
if t.Sym != nil {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
2015-02-13 14:40:36 -05:00
|
|
|
return
|
|
|
|
|
}
|
2016-08-30 13:50:03 -07:00
|
|
|
t = t.Elem()
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-30 13:50:03 -07:00
|
|
|
switch {
|
2017-02-27 19:56:38 +02:00
|
|
|
case t == nil || t.Broke():
|
2016-08-30 13:50:03 -07:00
|
|
|
// rely on typecheck having complained before
|
|
|
|
|
case t.Sym == nil:
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t)
|
2016-08-30 13:50:03 -07:00
|
|
|
case t.IsPtr():
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
2016-08-30 13:50:03 -07:00
|
|
|
case t.IsInterface():
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
|
2016-08-30 13:50:03 -07:00
|
|
|
default:
|
|
|
|
|
// Should have picked off all the reasons above,
|
|
|
|
|
// but just in case, fall back to generic error.
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
|
2016-08-30 13:50:03 -07:00
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 19:56:38 +02:00
|
|
|
if local && !mt.Local() {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("cannot define new methods on non-local type %v", mt)
|
2015-11-15 23:32:30 +01:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-11 17:12:31 -08:00
|
|
|
if isblanksym(msym) {
|
2015-11-15 23:32:30 +01:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 13:50:03 -07:00
|
|
|
if mt.IsStruct() {
|
|
|
|
|
for _, f := range mt.Fields().Slice() {
|
2016-03-11 17:12:31 -08:00
|
|
|
if f.Sym == msym {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("type %v has both field and method named %v", mt, msym)
|
2015-02-13 14:40:36 -05:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 13:50:03 -07:00
|
|
|
for _, f := range mt.Methods().Slice() {
|
2016-03-11 17:12:31 -08:00
|
|
|
if msym.Name != f.Sym.Name {
|
2015-02-13 14:40:36 -05:00
|
|
|
continue
|
|
|
|
|
}
|
2016-09-15 14:34:20 +10:00
|
|
|
// eqtype only checks that incoming and result parameters match,
|
cmd/compile: ignore receiver parameters in Eqtype
Receiver parameters generally aren't relevant to the function
signature type. In particular:
1. When checking whether a type's method implements an interface's
method, we specifically want to ignore the receiver parameters,
because they'll be different.
2. When checking interface type equality, interface methods always
use the same "fakethis" *struct{} type as their receiver.
3. Finally, method expressions and method values degenerate into
receiver-less function types.
The only case where we care about receiver types matching is in
addmethod, which is easily handled by adding an extra Eqtype check of
the receiver parameters. Also, added a test for this, since
(surprisingly) there weren't any.
As precedence, go/types.Identical ignores receiver parameters when
comparing go/types.Signature values.
Notably, this allows us to slightly simplify the "implements"
function, which is used for checking whether type/interface t
implements interface iface. Currently, cmd/compile actually works
around Eqtype's receiver parameter checking by creating new throwaway
TFUNC Types without the receiver parameter.
(Worse, the compiler currently only provides APIs to build TFUNC Types
from Nod syntax trees, so building those throwaway types also involves
first building throwaway syntax trees.)
Passes toolstash -cmp.
Change-Id: Ib07289c66feacee284e016bc312e8c5ff674714f
Reviewed-on: https://go-review.googlesource.com/20602
Reviewed-by: Robert Griesemer <gri@golang.org>
2016-03-11 14:38:16 -08:00
|
|
|
// so explicitly check that the receiver parameters match too.
|
2016-09-15 14:34:20 +10:00
|
|
|
if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) {
|
2016-09-15 15:45:10 +10:00
|
|
|
yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f := types.NewField()
|
2016-10-20 17:33:45 -07:00
|
|
|
f.Sym = msym
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
f.Nname = asTypesNode(newname(msym))
|
2016-10-20 17:33:45 -07:00
|
|
|
f.Type = t
|
2017-02-27 19:56:38 +02:00
|
|
|
f.SetNointerface(nointerface)
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2016-08-30 13:50:03 -07:00
|
|
|
mt.Methods().Append(f)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func funccompile(n *Node) {
|
|
|
|
|
if n.Type == nil {
|
|
|
|
|
if nerrors == 0 {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("funccompile missing type")
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// assign parameter offsets
|
|
|
|
|
checkwidth(n.Type)
|
|
|
|
|
|
|
|
|
|
if Curfn != nil {
|
2015-08-30 23:10:03 +02:00
|
|
|
Fatalf("funccompile %v inside %v", n.Func.Nname.Sym, Curfn.Func.Nname.Sym)
|
2015-02-13 14:40:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dclcontext = PAUTO
|
2016-09-16 00:33:29 +10:00
|
|
|
funcdepth = n.Func.Depth + 1
|
2015-02-13 14:40:36 -05:00
|
|
|
compile(n)
|
|
|
|
|
Curfn = nil
|
2016-09-16 00:33:29 +10:00
|
|
|
funcdepth = 0
|
2015-02-13 14:40:36 -05:00
|
|
|
dclcontext = PEXTERN
|
|
|
|
|
}
|
|
|
|
|
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func funcsymname(s *types.Sym) string {
|
2017-03-24 11:33:29 -07:00
|
|
|
return s.Name + "·f"
|
|
|
|
|
}
|
2015-02-13 14:40:36 -05:00
|
|
|
|
2017-03-24 11:33:29 -07:00
|
|
|
// funcsym returns s·f.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func funcsym(s *types.Sym) *types.Sym {
|
|
|
|
|
sf, existed := s.Pkg.LookupOK(funcsymname(s))
|
2017-03-24 11:33:29 -07:00
|
|
|
// Don't export s·f when compiling for dynamic linking.
|
|
|
|
|
// When dynamically linking, the necessary function
|
|
|
|
|
// symbols will be created explicitly with makefuncsym.
|
|
|
|
|
// See the makefuncsym comment for details.
|
|
|
|
|
if !Ctxt.Flag_dynlink && !existed {
|
|
|
|
|
funcsyms = append(funcsyms, s)
|
|
|
|
|
}
|
|
|
|
|
return sf
|
2015-07-13 20:50:51 -04:00
|
|
|
}
|
2015-07-15 11:31:30 +12:00
|
|
|
|
2017-03-24 11:33:29 -07:00
|
|
|
// makefuncsym ensures that s·f is exported.
|
|
|
|
|
// It is only used with -dynlink.
|
|
|
|
|
// When not compiling for dynamic linking,
|
|
|
|
|
// the funcsyms are created as needed by
|
|
|
|
|
// the packages that use them.
|
|
|
|
|
// Normally we emit the s·f stubs as DUPOK syms,
|
|
|
|
|
// but DUPOK doesn't work across shared library boundaries.
|
|
|
|
|
// So instead, when dynamic linking, we only create
|
|
|
|
|
// the s·f stubs in s's package.
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
func makefuncsym(s *types.Sym) {
|
2017-03-24 11:33:29 -07:00
|
|
|
if !Ctxt.Flag_dynlink {
|
|
|
|
|
Fatalf("makefuncsym dynlink")
|
|
|
|
|
}
|
2015-07-15 11:31:30 +12:00
|
|
|
if isblanksym(s) {
|
|
|
|
|
return
|
|
|
|
|
}
|
2016-04-13 18:37:18 -07:00
|
|
|
if compiling_runtime && s.Name == "getg" {
|
2015-07-15 11:31:30 +12:00
|
|
|
// runtime.getg() is not a real function and so does
|
|
|
|
|
// not get a funcsym.
|
|
|
|
|
return
|
|
|
|
|
}
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
if _, existed := s.Pkg.LookupOK(funcsymname(s)); !existed {
|
2017-03-24 11:33:29 -07:00
|
|
|
funcsyms = append(funcsyms, s)
|
2017-01-23 14:24:24 -08:00
|
|
|
}
|
2015-07-15 11:31:30 +12:00
|
|
|
}
|
2015-11-02 16:45:07 -05:00
|
|
|
|
|
|
|
|
type nowritebarrierrecChecker struct {
|
|
|
|
|
curfn *Node
|
|
|
|
|
stable bool
|
|
|
|
|
|
|
|
|
|
// best maps from the ODCLFUNC of each visited function that
|
|
|
|
|
// recursively invokes a write barrier to the called function
|
|
|
|
|
// on the shortest path to a write barrier.
|
|
|
|
|
best map[*Node]nowritebarrierrecCall
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type nowritebarrierrecCall struct {
|
|
|
|
|
target *Node
|
|
|
|
|
depth int
|
2016-12-15 17:17:01 -08:00
|
|
|
lineno src.XPos
|
2015-11-02 16:45:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func checknowritebarrierrec() {
|
|
|
|
|
c := nowritebarrierrecChecker{
|
|
|
|
|
best: make(map[*Node]nowritebarrierrecCall),
|
|
|
|
|
}
|
|
|
|
|
visitBottomUp(xtop, func(list []*Node, recursive bool) {
|
|
|
|
|
// Functions with write barriers have depth 0.
|
|
|
|
|
for _, n := range list {
|
2017-03-30 11:40:06 -07:00
|
|
|
if n.Func.WBPos.IsKnown() && n.Func.Pragma&Nowritebarrier != 0 {
|
|
|
|
|
yyerrorl(n.Func.WBPos, "write barrier prohibited")
|
|
|
|
|
}
|
2016-12-07 17:40:46 -08:00
|
|
|
if n.Func.WBPos.IsKnown() && n.Func.Pragma&Yeswritebarrierrec == 0 {
|
|
|
|
|
c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBPos}
|
2015-11-02 16:45:07 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Propagate write barrier depth up from callees. In
|
|
|
|
|
// the recursive case, we have to update this at most
|
|
|
|
|
// len(list) times and can stop when we an iteration
|
|
|
|
|
// that doesn't change anything.
|
|
|
|
|
for _ = range list {
|
|
|
|
|
c.stable = false
|
|
|
|
|
for _, n := range list {
|
2016-10-10 16:46:28 -04:00
|
|
|
if n.Func.Pragma&Yeswritebarrierrec != 0 {
|
|
|
|
|
// Don't propagate write
|
|
|
|
|
// barrier up to a
|
|
|
|
|
// yeswritebarrierrec function.
|
|
|
|
|
continue
|
|
|
|
|
}
|
2016-12-07 17:40:46 -08:00
|
|
|
if !n.Func.WBPos.IsKnown() {
|
2015-11-02 16:45:07 -05:00
|
|
|
c.curfn = n
|
2016-03-03 16:27:05 -08:00
|
|
|
c.visitcodelist(n.Nbody)
|
2015-11-02 16:45:07 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if c.stable {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check nowritebarrierrec functions.
|
|
|
|
|
for _, n := range list {
|
2016-02-26 13:32:28 -08:00
|
|
|
if n.Func.Pragma&Nowritebarrierrec == 0 {
|
2015-11-02 16:45:07 -05:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
call, hasWB := c.best[n]
|
|
|
|
|
if !hasWB {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build the error message in reverse.
|
|
|
|
|
err := ""
|
|
|
|
|
for call.target != nil {
|
2016-03-02 11:30:29 -08:00
|
|
|
err = fmt.Sprintf("\n\t%v: called by %v%s", linestr(call.lineno), n.Func.Nname, err)
|
2015-11-02 16:45:07 -05:00
|
|
|
n = call.target
|
|
|
|
|
call = c.best[n]
|
|
|
|
|
}
|
|
|
|
|
err = fmt.Sprintf("write barrier prohibited by caller; %v%s", n.Func.Nname, err)
|
2016-12-07 17:40:46 -08:00
|
|
|
yyerrorl(n.Func.WBPos, err)
|
2015-11-02 16:45:07 -05:00
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-08 10:26:20 -08:00
|
|
|
func (c *nowritebarrierrecChecker) visitcodelist(l Nodes) {
|
2016-03-08 15:10:26 -08:00
|
|
|
for _, n := range l.Slice() {
|
|
|
|
|
c.visitcode(n)
|
2016-02-27 14:31:33 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-02 16:45:07 -05:00
|
|
|
func (c *nowritebarrierrecChecker) visitcode(n *Node) {
|
|
|
|
|
if n == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if n.Op == OCALLFUNC || n.Op == OCALLMETH {
|
|
|
|
|
c.visitcall(n)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
c.visitcodelist(n.Ninit)
|
|
|
|
|
c.visitcode(n.Left)
|
|
|
|
|
c.visitcode(n.Right)
|
|
|
|
|
c.visitcodelist(n.List)
|
2016-03-03 16:27:05 -08:00
|
|
|
c.visitcodelist(n.Nbody)
|
2015-11-02 16:45:07 -05:00
|
|
|
c.visitcodelist(n.Rlist)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *nowritebarrierrecChecker) visitcall(n *Node) {
|
|
|
|
|
fn := n.Left
|
|
|
|
|
if n.Op == OCALLMETH {
|
cmd/compile: factor out Pkg, Sym, and Type into package types
- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
file which contains a handful of functions that must be installed
early by the gc frontend
- to break cycles, for now we need two functions to convert between
*gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
types.NewPtr, types.NewArray, etc.
Passes toolstash-check -all.
Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-04-04 17:54:02 -07:00
|
|
|
fn = asNode(n.Left.Sym.Def)
|
2015-11-02 16:45:07 -05:00
|
|
|
}
|
|
|
|
|
if fn == nil || fn.Op != ONAME || fn.Class != PFUNC || fn.Name.Defn == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
defn := fn.Name.Defn
|
|
|
|
|
|
|
|
|
|
fnbest, ok := c.best[defn]
|
|
|
|
|
if !ok {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
best, ok := c.best[c.curfn]
|
|
|
|
|
if ok && fnbest.depth+1 >= best.depth {
|
|
|
|
|
return
|
|
|
|
|
}
|
2016-12-07 17:40:46 -08:00
|
|
|
c.best[c.curfn] = nowritebarrierrecCall{target: defn, depth: fnbest.depth + 1, lineno: n.Pos}
|
2015-11-02 16:45:07 -05:00
|
|
|
c.stable = false
|
|
|
|
|
}
|