aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2020-12-21 01:36:15 -0500
committerRuss Cox <rsc@golang.org>2020-12-21 19:23:30 +0000
commit4836e28ac0482183a3a6af88ee4295ffdbc94f62 (patch)
treee979010cc2cf17aac1d5d17bdb9043919fa9422a /src/cmd
parent85ce6ecfe3c54075c7bc53538940f0319b57068b (diff)
downloadgo-4836e28ac0482183a3a6af88ee4295ffdbc94f62.tar.gz
go-4836e28ac0482183a3a6af88ee4295ffdbc94f62.zip
[dev.regabi] cmd/compile: separate noder more cleanly
Separate embed, cgo pragmas, and Main trackScopes variable from noder more cleanly. This lets us split embed and noder into new packages. It also assumes that the local embedded variables will be removed and deletes them now for simplicity. Change-Id: I9638bcc2c5f0e76440de056c6285b6aa2f73a00d Reviewed-on: https://go-review.googlesource.com/c/go/+/279299 Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/compile/internal/gc/embed.go51
-rw-r--r--src/cmd/compile/internal/gc/go.go6
-rw-r--r--src/cmd/compile/internal/gc/main.go17
-rw-r--r--src/cmd/compile/internal/gc/noder.go26
-rw-r--r--src/cmd/compile/internal/ir/name.go50
5 files changed, 66 insertions, 84 deletions
diff --git a/src/cmd/compile/internal/gc/embed.go b/src/cmd/compile/internal/gc/embed.go
index 7d67d2dfd0..0d4ce83716 100644
--- a/src/cmd/compile/internal/gc/embed.go
+++ b/src/cmd/compile/internal/gc/embed.go
@@ -24,8 +24,6 @@ const (
embedFiles
)
-var numLocalEmbed int
-
func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds []PragmaEmbed) (newExprs []ir.Node) {
haveEmbed := false
for _, decl := range p.file.DeclList {
@@ -63,25 +61,39 @@ func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds [
p.errorAt(pos, "go:embed cannot apply to var without type")
return exprs
}
+ if dclcontext != ir.PEXTERN {
+ p.errorAt(pos, "go:embed cannot apply to var inside func")
+ return exprs
+ }
+
+ v := names[0].(*ir.Name)
+ Target.Embeds = append(Target.Embeds, v)
+ v.Embed = new([]ir.Embed)
+ for _, e := range embeds {
+ *v.Embed = append(*v.Embed, ir.Embed{Pos: p.makeXPos(e.Pos), Patterns: e.Patterns})
+ }
+ return exprs
+}
- kind := embedKindApprox(typ)
+func embedFileList(v *ir.Name) []string {
+ kind := embedKind(v.Type())
if kind == embedUnknown {
- p.errorAt(pos, "go:embed cannot apply to var of type %v", typ)
- return exprs
+ base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
+ return nil
}
// Build list of files to store.
have := make(map[string]bool)
var list []string
- for _, e := range embeds {
+ for _, e := range *v.Embed {
for _, pattern := range e.Patterns {
files, ok := base.Flag.Cfg.Embed.Patterns[pattern]
if !ok {
- p.errorAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
+ base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
}
for _, file := range files {
if base.Flag.Cfg.Embed.Files[file] == "" {
- p.errorAt(e.Pos, "invalid go:embed: build system did not map file: %s", file)
+ base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map file: %s", file)
continue
}
if !have[file] {
@@ -103,25 +115,12 @@ func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds [
if kind == embedString || kind == embedBytes {
if len(list) > 1 {
- p.errorAt(pos, "invalid go:embed: multiple files for type %v", typ)
- return exprs
+ base.ErrorfAt(v.Pos(), "invalid go:embed: multiple files for type %v", v.Type())
+ return nil
}
}
- v := names[0].(*ir.Name)
- if dclcontext != ir.PEXTERN {
- numLocalEmbed++
- v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed))
- v.Sym().Def = v
- v.Name().Ntype = typ
- v.SetClass(ir.PEXTERN)
- Target.Externs = append(Target.Externs, v)
- exprs = []ir.Node{v}
- }
-
- v.Name().SetEmbedFiles(list)
- Target.Embeds = append(Target.Embeds, v)
- return exprs
+ return list
}
// embedKindApprox determines the kind of embedding variable, approximately.
@@ -192,8 +191,8 @@ func dumpembeds() {
// initEmbed emits the init data for a //go:embed variable,
// which is either a string, a []byte, or an embed.FS.
-func initEmbed(v ir.Node) {
- files := v.Name().EmbedFiles()
+func initEmbed(v *ir.Name) {
+ files := embedFileList(v)
switch kind := embedKind(v.Type()); kind {
case embedUnknown:
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index b092e6933c..1707e6a11b 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -116,13 +116,14 @@ var (
okforadd [types.NTYPE]bool
okforand [types.NTYPE]bool
okfornone [types.NTYPE]bool
- okforcmp [types.NTYPE]bool
okforbool [types.NTYPE]bool
okforcap [types.NTYPE]bool
okforlen [types.NTYPE]bool
okforarith [types.NTYPE]bool
)
+var okforcmp [types.NTYPE]bool
+
var (
okfor [ir.OEND][]bool
iscmp [ir.OEND]bool
@@ -149,9 +150,6 @@ var typecheckok bool
// when the race detector is enabled.
var instrumenting bool
-// Whether we are tracking lexical scopes for DWARF.
-var trackScopes bool
-
var nodfp *ir.Name
var autogeneratedPos src.XPos
diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index 545491daa1..45880c5cde 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -205,8 +205,6 @@ func Main(archInit func(*Arch)) {
}
}
- trackScopes = base.Flag.Dwarf
-
Widthptr = thearch.LinkArch.PtrSize
Widthreg = thearch.LinkArch.RegSize
@@ -226,6 +224,7 @@ func Main(archInit func(*Arch)) {
timings.Start("fe", "parse")
lines := parseFiles(flag.Args())
+ cgoSymABIs()
timings.Stop()
timings.AddEvent(int64(lines), "lines")
@@ -477,6 +476,20 @@ func Main(archInit func(*Arch)) {
}
}
+func cgoSymABIs() {
+ // The linker expects an ABI0 wrapper for all cgo-exported
+ // functions.
+ for _, prag := range Target.CgoPragmas {
+ switch prag[0] {
+ case "cgo_export_static", "cgo_export_dynamic":
+ if symabiRefs == nil {
+ symabiRefs = make(map[string]obj.ABI)
+ }
+ symabiRefs[prag[1]] = obj.ABI0
+ }
+ }
+}
+
// numNonClosures returns the number of functions in list which are not closures.
func numNonClosures(list []*ir.Func) int {
count := 0
diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go
index 10eac6e815..ee01423833 100644
--- a/src/cmd/compile/internal/gc/noder.go
+++ b/src/cmd/compile/internal/gc/noder.go
@@ -20,7 +20,6 @@ import (
"cmd/compile/internal/ir"
"cmd/compile/internal/syntax"
"cmd/compile/internal/types"
- "cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
)
@@ -36,8 +35,9 @@ func parseFiles(filenames []string) uint {
for _, filename := range filenames {
p := &noder{
- basemap: make(map[*syntax.PosBase]*src.PosBase),
- err: make(chan syntax.Error),
+ basemap: make(map[*syntax.PosBase]*src.PosBase),
+ err: make(chan syntax.Error),
+ trackScopes: base.Flag.Dwarf,
}
noders = append(noders, p)
@@ -151,7 +151,8 @@ type noder struct {
// scopeVars is a stack tracking the number of variables declared in the
// current function at the moment each open scope was opened.
- scopeVars []int
+ trackScopes bool
+ scopeVars []int
lastCloseScopePos syntax.Pos
}
@@ -179,7 +180,7 @@ func (p *noder) funcBody(fn *ir.Func, block *syntax.BlockStmt) {
func (p *noder) openScope(pos syntax.Pos) {
types.Markdcl()
- if trackScopes {
+ if p.trackScopes {
Curfn.Parents = append(Curfn.Parents, p.scope)
p.scopeVars = append(p.scopeVars, len(Curfn.Dcl))
p.scope = ir.ScopeID(len(Curfn.Parents))
@@ -192,7 +193,7 @@ func (p *noder) closeScope(pos syntax.Pos) {
p.lastCloseScopePos = pos
types.Popdcl()
- if trackScopes {
+ if p.trackScopes {
scopeVars := p.scopeVars[len(p.scopeVars)-1]
p.scopeVars = p.scopeVars[:len(p.scopeVars)-1]
if scopeVars == len(Curfn.Dcl) {
@@ -284,19 +285,6 @@ func (p *noder) processPragmas() {
}
n.Sym().Linkname = l.remote
}
-
- // The linker expects an ABI0 wrapper for all cgo-exported
- // functions.
- for _, prag := range p.pragcgobuf {
- switch prag[0] {
- case "cgo_export_static", "cgo_export_dynamic":
- if symabiRefs == nil {
- symabiRefs = make(map[string]obj.ABI)
- }
- symabiRefs[prag[1]] = obj.ABI0
- }
- }
-
Target.CgoPragmas = append(Target.CgoPragmas, p.pragcgobuf...)
}
diff --git a/src/cmd/compile/internal/ir/name.go b/src/cmd/compile/internal/ir/name.go
index 0c36ffdf7a..f5f4280fd0 100644
--- a/src/cmd/compile/internal/ir/name.go
+++ b/src/cmd/compile/internal/ir/name.go
@@ -34,16 +34,16 @@ func (*Ident) CanBeNtype() {}
// Name holds Node fields used only by named nodes (ONAME, OTYPE, some OLITERAL).
type Name struct {
miniExpr
- BuiltinOp Op // uint8
- Class_ Class // uint8
- flags bitset16
- pragma PragmaFlag // int16
- sym *types.Sym
- fn *Func
- Offset_ int64
- val constant.Value
- orig Node
- embedFiles *[]string // list of embedded files, for ONAME var
+ BuiltinOp Op // uint8
+ Class_ Class // uint8
+ flags bitset16
+ pragma PragmaFlag // int16
+ sym *types.Sym
+ fn *Func
+ Offset_ int64
+ val constant.Value
+ orig Node
+ Embed *[]Embed // list of embedded files, for ONAME var
PkgName *PkgName // real package for import . names
// For a local variable (not param) or extern, the initializing assignment (OAS or OAS2).
@@ -139,14 +139,14 @@ type Name struct {
Outer *Name
}
+func (n *Name) isExpr() {}
+
// CloneName makes a cloned copy of the name.
// It's not ir.Copy(n) because in general that operation is a mistake on names,
// which uniquely identify variables.
// Callers must use n.CloneName to make clear they intend to create a separate name.
func (n *Name) CloneName() *Name { c := *n; return &c }
-func (n *Name) isExpr() {}
-
// NewNameAt returns a new ONAME Node associated with symbol s at position pos.
// The caller is responsible for setting Curfn.
func NewNameAt(pos src.XPos, sym *types.Sym) *Name {
@@ -231,27 +231,6 @@ func (n *Name) Alias() bool { return n.flags&nameAlias != 0 }
// SetAlias sets whether p, which must be for an OTYPE, is a type alias.
func (n *Name) SetAlias(alias bool) { n.flags.set(nameAlias, alias) }
-// EmbedFiles returns the list of embedded files for p,
-// which must be for an ONAME var.
-func (n *Name) EmbedFiles() []string {
- if n.embedFiles == nil {
- return nil
- }
- return *n.embedFiles
-}
-
-// SetEmbedFiles sets the list of embedded files for p,
-// which must be for an ONAME var.
-func (n *Name) SetEmbedFiles(list []string) {
- if n.embedFiles == nil && list == nil {
- return
- }
- if n.embedFiles == nil {
- n.embedFiles = new([]string)
- }
- *n.embedFiles = list
-}
-
const (
nameCaptured = 1 << iota // is the variable captured by a closure
nameReadonly
@@ -389,6 +368,11 @@ const (
_ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3)
)
+type Embed struct {
+ Pos src.XPos
+ Patterns []string
+}
+
// A Pack is an identifier referring to an imported package.
type PkgName struct {
miniNode