From: Matthew Dempsky Date: Tue, 19 Sep 2017 19:45:17 +0000 (-0700) Subject: cmd/compile/internal/types: simplify dclstack X-Git-Tag: go1.10beta1~1047 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=a53e853964cc9220ebc4b35aeb81a382939fb479;p=gostls13.git cmd/compile/internal/types: simplify dclstack We used to backup symbol declarations using complete Syms, but this was unnecessary: very few of Sym's fields were actually needed. Also, to restore a symbol, we had to re-Lookup the Sym in its Pkg. By introducing a new dedicated dsym type for this purpose, we can address both of these deficiencies. Passes toolstash-check. Change-Id: I39f3d672b301f84a3a62b9b34b4b2770cb25df79 Reviewed-on: https://go-review.googlesource.com/64811 Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- diff --git a/src/cmd/compile/internal/types/scope.go b/src/cmd/compile/internal/types/scope.go index 072b8089b0..aef3b3bbe0 100644 --- a/src/cmd/compile/internal/types/scope.go +++ b/src/cmd/compile/internal/types/scope.go @@ -4,65 +4,74 @@ package types +import "cmd/internal/src" + // Declaration stack & operations var blockgen int32 = 1 // max block number var Block int32 // current block number -// dclstack maintains a stack of shadowed symbol declarations so that -// Popdcl can restore their declarations when a block scope ends. -// -// The Syms on this stack 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. -var dclstack []*Sym - -func dcopy(a, b *Sym) { - a.Pkg = b.Pkg - a.Name = b.Name - a.Def = b.Def - a.Block = b.Block - a.Lastlineno = b.Lastlineno +// A dsym stores a symbol's shadowed declaration so that it can be +// restored once the block scope ends. +type dsym struct { + sym *Sym // sym == nil indicates stack mark + def *Node + block int32 + lastlineno src.XPos // last declaration for diagnostic } -func push() *Sym { - d := new(Sym) - dclstack = append(dclstack, d) - return d -} +// dclstack maintains a stack of shadowed symbol declarations so that +// Popdcl can restore their declarations when a block scope ends. +var dclstack []dsym // 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. func Pushdcl(s *Sym) { - dcopy(push(), s) + dclstack = append(dclstack, dsym{ + sym: s, + def: s.Def, + block: s.Block, + lastlineno: s.Lastlineno, + }) } // Popdcl pops the innermost block scope and restores all symbol declarations // to their previous state. func Popdcl() { for i := len(dclstack); i > 0; i-- { - d := dclstack[i-1] - if d.Name == "" { + d := &dclstack[i-1] + s := d.sym + if s == nil { // pop stack mark - Block = d.Block + Block = d.block dclstack = dclstack[:i-1] return } - dcopy(d.Pkg.Lookup(d.Name), d) + + s.Def = d.def + s.Block = d.block + s.Lastlineno = d.lastlineno + + // Clear dead pointer fields. + d.sym = nil + d.def = nil } Fatalf("popdcl: no stack mark") } // Markdcl records the start of a new block scope for declarations. func Markdcl() { - push().Block = Block // stack mark (Name == "") + dclstack = append(dclstack, dsym{ + sym: nil, // stack mark + block: Block, + }) blockgen++ Block = blockgen } func IsDclstackValid() bool { for _, d := range dclstack { - if d.Name == "" { + if d.sym == nil { return false } } diff --git a/src/cmd/compile/internal/types/sym.go b/src/cmd/compile/internal/types/sym.go index f79b07b16c..1b9d01dab5 100644 --- a/src/cmd/compile/internal/types/sym.go +++ b/src/cmd/compile/internal/types/sym.go @@ -21,9 +21,10 @@ type Sym struct { Importdef *Pkg // where imported definition was found Linkname string // link name + Pkg *Pkg + Name string // object name + // saved and restored by dcopy - Pkg *Pkg - Name string // object name Def *Node // definition: ONAME OTYPE OPACK or OLITERAL Block int32 // blocknumber to catch redeclaration Lastlineno src.XPos // last declaration for diagnostic