aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--src/embed/internal/embedtest/embed_test.go28
-rw-r--r--src/embed/internal/embedtest/embedx_test.go14
7 files changed, 72 insertions, 120 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
diff --git a/src/embed/internal/embedtest/embed_test.go b/src/embed/internal/embedtest/embed_test.go
index c6a7bea7a3..04c23172c2 100644
--- a/src/embed/internal/embedtest/embed_test.go
+++ b/src/embed/internal/embedtest/embed_test.go
@@ -73,24 +73,14 @@ func TestGlobal(t *testing.T) {
testString(t, string(glass), "glass", "I can eat glass and it doesn't hurt me.\n")
}
-func TestLocal(t *testing.T) {
- //go:embed testdata/k*.txt
- var local embed.FS
- testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")
-
- //go:embed testdata/k*.txt
- var s string
- testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
-
- //go:embed testdata/h*.txt
- var b []byte
- testString(t, string(b), "local variable b", "hello, world\n")
-}
+//go:embed testdata
+var dir embed.FS
-func TestDir(t *testing.T) {
- //go:embed testdata
- var all embed.FS
+//go:embed testdata/*
+var star embed.FS
+func TestDir(t *testing.T) {
+ all := dir
testFiles(t, all, "testdata/hello.txt", "hello, world\n")
testFiles(t, all, "testdata/i/i18n.txt", "internationalization\n")
testFiles(t, all, "testdata/i/j/k/k8s.txt", "kubernetes\n")
@@ -103,12 +93,6 @@ func TestDir(t *testing.T) {
}
func TestHidden(t *testing.T) {
- //go:embed testdata
- var dir embed.FS
-
- //go:embed testdata/*
- var star embed.FS
-
t.Logf("//go:embed testdata")
testDir(t, dir, "testdata",
diff --git a/src/embed/internal/embedtest/embedx_test.go b/src/embed/internal/embedtest/embedx_test.go
index 20d5a28c11..27fa11614e 100644
--- a/src/embed/internal/embedtest/embedx_test.go
+++ b/src/embed/internal/embedtest/embedx_test.go
@@ -90,17 +90,3 @@ func TestXGlobal(t *testing.T) {
}
bbig[0] = old
}
-
-func TestXLocal(t *testing.T) {
- //go:embed testdata/*o.txt
- var local embed.FS
- testFiles(t, local, "testdata/hello.txt", "hello, world\n")
-
- //go:embed testdata/k*.txt
- var s string
- testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
-
- //go:embed testdata/h*.txt
- var b []byte
- testString(t, string(b), "local variable b", "hello, world\n")
-}