Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / go / typechecker / scope.go
blobc2ec75905096f7d5d31a63191c45e2a3f0fa8a99
1 // Copyright 2010 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.
5 // This file implements scope support functions.
7 package typechecker
9 import (
10 "fmt"
11 "go/ast"
12 "go/token"
16 func (tc *typechecker) openScope() *ast.Scope {
17 tc.topScope = ast.NewScope(tc.topScope)
18 return tc.topScope
22 func (tc *typechecker) closeScope() {
23 tc.topScope = tc.topScope.Outer
27 // objPos computes the source position of the declaration of an object name.
28 // Only required for error reporting, so doesn't have to be fast.
29 func objPos(obj *ast.Object) (pos token.Position) {
30 switch d := obj.Decl.(type) {
31 case *ast.Field:
32 for _, n := range d.Names {
33 if n.Name == obj.Name {
34 return n.Pos()
37 case *ast.ValueSpec:
38 for _, n := range d.Names {
39 if n.Name == obj.Name {
40 return n.Pos()
43 case *ast.TypeSpec:
44 return d.Name.Pos()
45 case *ast.FuncDecl:
46 return d.Name.Pos()
48 if debug {
49 fmt.Printf("decl = %T\n", obj.Decl)
51 panic("unreachable")
55 // declInScope declares an object of a given kind and name in scope and sets the object's Decl and N fields.
56 // It returns the newly allocated object. If an object with the same name already exists in scope, an error
57 // is reported and the object is not inserted.
58 // (Objects with _ name are always inserted into a scope without errors, but they cannot be found.)
59 func (tc *typechecker) declInScope(scope *ast.Scope, kind ast.Kind, name *ast.Ident, decl interface{}, n int) *ast.Object {
60 obj := ast.NewObj(kind, name.Name)
61 obj.Decl = decl
62 obj.N = n
63 name.Obj = obj
64 if alt := scope.Insert(obj); alt != obj {
65 tc.Errorf(name.Pos(), "%s already declared at %s", name.Name, objPos(alt))
67 return obj
71 // decl is the same as declInScope(tc.topScope, ...)
72 func (tc *typechecker) decl(kind ast.Kind, name *ast.Ident, decl interface{}, n int) *ast.Object {
73 return tc.declInScope(tc.topScope, kind, name, decl, n)
77 // find returns the object with the given name if visible in the current scope hierarchy.
78 // If no such object is found, an error is reported and a bad object is returned instead.
79 func (tc *typechecker) find(name *ast.Ident) (obj *ast.Object) {
80 for s := tc.topScope; s != nil && obj == nil; s = s.Outer {
81 obj = s.Lookup(name.Name)
83 if obj == nil {
84 tc.Errorf(name.Pos(), "%s not declared", name.Name)
85 obj = ast.NewObj(ast.Bad, name.Name)
87 name.Obj = obj
88 return
92 // findField returns the object with the given name if visible in the type's scope.
93 // If no such object is found, an error is reported and a bad object is returned instead.
94 func (tc *typechecker) findField(typ *ast.Type, name *ast.Ident) (obj *ast.Object) {
95 // TODO(gri) This is simplistic at the moment and ignores anonymous fields.
96 obj = typ.Scope.Lookup(name.Name)
97 if obj == nil {
98 tc.Errorf(name.Pos(), "%s not declared", name.Name)
99 obj = ast.NewObj(ast.Bad, name.Name)
101 return
105 // printScope prints the objects in a scope.
106 func printScope(scope *ast.Scope) {
107 fmt.Printf("scope %p {", scope)
108 if scope != nil && len(scope.Objects) > 0 {
109 fmt.Println()
110 for _, obj := range scope.Objects {
111 form := "void"
112 if obj.Type != nil {
113 form = obj.Type.Form.String()
115 fmt.Printf("\t%s\t%s\n", obj.Name, form)
118 fmt.Printf("}\n")