Black Lives Matter. Support the Equal Justice Initiative.

Source file src/cmd/compile/internal/noder/scopes.go

Documentation: cmd/compile/internal/noder

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package noder
     6  
     7  import (
     8  	"strings"
     9  
    10  	"cmd/compile/internal/base"
    11  	"cmd/compile/internal/ir"
    12  	"cmd/compile/internal/syntax"
    13  	"cmd/compile/internal/types2"
    14  )
    15  
    16  // recordScopes populates fn.Parents and fn.Marks based on the scoping
    17  // information provided by types2.
    18  func (g *irgen) recordScopes(fn *ir.Func, sig *syntax.FuncType) {
    19  	scope, ok := g.info.Scopes[sig]
    20  	if !ok {
    21  		base.FatalfAt(fn.Pos(), "missing scope for %v", fn)
    22  	}
    23  
    24  	for i, n := 0, scope.NumChildren(); i < n; i++ {
    25  		g.walkScope(scope.Child(i))
    26  	}
    27  
    28  	g.marker.WriteTo(fn)
    29  }
    30  
    31  func (g *irgen) walkScope(scope *types2.Scope) bool {
    32  	// types2 doesn't provide a proper API for determining the
    33  	// lexical element a scope represents, so we have to resort to
    34  	// string matching. Conveniently though, this allows us to
    35  	// skip both function types and function literals, neither of
    36  	// which are interesting to us here.
    37  	if strings.HasPrefix(scope.String(), "function scope ") {
    38  		return false
    39  	}
    40  
    41  	g.marker.Push(g.pos(scope))
    42  
    43  	haveVars := false
    44  	for _, name := range scope.Names() {
    45  		if obj, ok := scope.Lookup(name).(*types2.Var); ok && obj.Name() != "_" {
    46  			haveVars = true
    47  			break
    48  		}
    49  	}
    50  
    51  	for i, n := 0, scope.NumChildren(); i < n; i++ {
    52  		if g.walkScope(scope.Child(i)) {
    53  			haveVars = true
    54  		}
    55  	}
    56  
    57  	if haveVars {
    58  		g.marker.Pop(g.end(scope))
    59  	} else {
    60  		g.marker.Unpush()
    61  	}
    62  
    63  	return haveVars
    64  }
    65  

View as plain text