Commit 1368977a authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile/internal/types: remove Sym.Link field

The dclstack is now a proper stack and thus we can implement it
using a slice rather than a linked list.

Change-Id: I200e85621ff76c111bdeb7eb382fd82da438f3ba
Reviewed-on: https://go-review.googlesource.com/41135Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 33fd319c
...@@ -4,10 +4,7 @@ ...@@ -4,10 +4,7 @@
package types package types
import ( import "cmd/internal/src"
"cmd/internal/src"
"fmt"
)
// Declaration stack & operations // Declaration stack & operations
...@@ -16,17 +13,11 @@ var Block int32 // current block number ...@@ -16,17 +13,11 @@ var Block int32 // current block number
// dclstack maintains a stack of shadowed symbol declarations so that // dclstack maintains a stack of shadowed symbol declarations so that
// popdcl can restore their declarations when a block scope ends. // 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 // The Syms on this stack are not "real" Syms as they don't actually
// 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 // represent object names. Sym is just a convenient type for saving shadowed
// Sym definitions, and only a subset of its fields are actually used. // Sym definitions, and only a subset of its fields are actually used.
var dclstack *Sym var dclstack []*Sym
func dcopy(a, b *Sym) { func dcopy(a, b *Sym) {
a.Pkg = b.Pkg a.Pkg = b.Pkg
...@@ -39,8 +30,7 @@ func dcopy(a, b *Sym) { ...@@ -39,8 +30,7 @@ func dcopy(a, b *Sym) {
func push(pos src.XPos) *Sym { func push(pos src.XPos) *Sym {
d := new(Sym) d := new(Sym)
d.Lastlineno = pos d.Lastlineno = pos
d.Link = dclstack dclstack = append(dclstack, d)
dclstack = d
return d return d
} }
...@@ -54,48 +44,38 @@ func Pushdcl(s *Sym, pos src.XPos) { ...@@ -54,48 +44,38 @@ func Pushdcl(s *Sym, pos src.XPos) {
// Popdcl pops the innermost block scope and restores all symbol declarations // Popdcl pops the innermost block scope and restores all symbol declarations
// to their previous state. // to their previous state.
func Popdcl() { func Popdcl() {
d := dclstack i := len(dclstack)
for ; d != nil && d.Name != ""; d = d.Link { for ; i > 0; i-- {
d := dclstack[i-1]
if d.Name == "" {
break
}
s := d.Pkg.Lookup(d.Name) s := d.Pkg.Lookup(d.Name)
lno := s.Lastlineno lno := s.Lastlineno
dcopy(s, d) dcopy(s, d)
d.Lastlineno = lno d.Lastlineno = lno
} }
if d == nil { if i == 0 {
Fatalf("popdcl: no mark") Fatalf("popdcl: no mark")
} }
dclstack = d.Link // pop mark Block = dclstack[i-1].Block
Block = d.Block dclstack = dclstack[:i-1] // pop mark
} }
// Markdcl records the start of a new block scope for declarations. // Markdcl records the start of a new block scope for declarations.
func Markdcl(lineno src.XPos) { func Markdcl(lineno src.XPos) {
d := push(lineno) d := push(lineno)
d.Name = "" // used as a mark in fifo d.Name = "" // used as stack mark
d.Block = Block d.Block = Block
blockgen++ blockgen++
Block = blockgen Block = blockgen
} }
// keep around for debugging
func DumpDclstack() {
i := 0
for d := dclstack; d != nil; d = d.Link {
fmt.Printf("%6d %p", i, d)
if d.Name != "" {
fmt.Printf(" '%s' %v\n", d.Name, d.Pkg.Lookup(d.Name))
} else {
fmt.Printf(" ---\n")
}
i++
}
}
func IsDclstackValid() bool { func IsDclstackValid() bool {
for d := dclstack; d != nil; d = d.Link { for _, d := range dclstack {
if d.Name == "" { if d.Name == "" {
return false return false
} }
......
...@@ -22,7 +22,7 @@ func TestSizeof(t *testing.T) { ...@@ -22,7 +22,7 @@ func TestSizeof(t *testing.T) {
_32bit uintptr // size on 32bit platforms _32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms _64bit uintptr // size on 64bit platforms
}{ }{
{Sym{}, 60, 104}, {Sym{}, 56, 96},
{Type{}, 52, 88}, {Type{}, 52, 88},
{Map{}, 20, 40}, {Map{}, 20, 40},
{Forward{}, 20, 32}, {Forward{}, 20, 32},
......
...@@ -18,7 +18,6 @@ import ( ...@@ -18,7 +18,6 @@ import (
// allows using Sym pointer equality to test for Go identifier uniqueness when // allows using Sym pointer equality to test for Go identifier uniqueness when
// handling selector expressions. // handling selector expressions.
type Sym struct { type Sym struct {
Link *Sym
Importdef *Pkg // where imported definition was found Importdef *Pkg // where imported definition was found
Linkname string // link name Linkname string // link name
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment