* tree-ssa-reassoc.c (reassociate_bb): Clarify code slighly.
[official-gcc.git] / libgo / go / go / types / decl.go
blob7428f8f99500a78a03a8e8798237095637e4e9ed
1 // Copyright 2014 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 package types
7 import (
8 "go/ast"
9 "go/constant"
10 "go/token"
13 func (check *Checker) reportAltDecl(obj Object) {
14 if pos := obj.Pos(); pos.IsValid() {
15 // We use "other" rather than "previous" here because
16 // the first declaration seen may not be textually
17 // earlier in the source.
18 check.errorf(pos, "\tother declaration of %s", obj.Name()) // secondary error, \t indented
22 func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) {
23 // spec: "The blank identifier, represented by the underscore
24 // character _, may be used in a declaration like any other
25 // identifier but the declaration does not introduce a new
26 // binding."
27 if obj.Name() != "_" {
28 if alt := scope.Insert(obj); alt != nil {
29 check.errorf(obj.Pos(), "%s redeclared in this block", obj.Name())
30 check.reportAltDecl(alt)
31 return
33 obj.setScopePos(pos)
35 if id != nil {
36 check.recordDef(id, obj)
40 // objDecl type-checks the declaration of obj in its respective (file) context.
41 // See check.typ for the details on def and path.
42 func (check *Checker) objDecl(obj Object, def *Named, path []*TypeName) {
43 if obj.Type() != nil {
44 return // already checked - nothing to do
47 if trace {
48 check.trace(obj.Pos(), "-- declaring %s", obj.Name())
49 check.indent++
50 defer func() {
51 check.indent--
52 check.trace(obj.Pos(), "=> %s", obj)
53 }()
56 d := check.objMap[obj]
57 if d == nil {
58 check.dump("%s: %s should have been declared", obj.Pos(), obj.Name())
59 unreachable()
62 // save/restore current context and setup object context
63 defer func(ctxt context) {
64 check.context = ctxt
65 }(check.context)
66 check.context = context{
67 scope: d.file,
70 // Const and var declarations must not have initialization
71 // cycles. We track them by remembering the current declaration
72 // in check.decl. Initialization expressions depending on other
73 // consts, vars, or functions, add dependencies to the current
74 // check.decl.
75 switch obj := obj.(type) {
76 case *Const:
77 check.decl = d // new package-level const decl
78 check.constDecl(obj, d.typ, d.init)
79 case *Var:
80 check.decl = d // new package-level var decl
81 check.varDecl(obj, d.lhs, d.typ, d.init)
82 case *TypeName:
83 // invalid recursive types are detected via path
84 check.typeDecl(obj, d.typ, def, path, d.alias)
85 case *Func:
86 // functions may be recursive - no need to track dependencies
87 check.funcDecl(obj, d)
88 default:
89 unreachable()
93 func (check *Checker) constDecl(obj *Const, typ, init ast.Expr) {
94 assert(obj.typ == nil)
96 if obj.visited {
97 obj.typ = Typ[Invalid]
98 return
100 obj.visited = true
102 // use the correct value of iota
103 assert(check.iota == nil)
104 check.iota = obj.val
105 defer func() { check.iota = nil }()
107 // provide valid constant value under all circumstances
108 obj.val = constant.MakeUnknown()
110 // determine type, if any
111 if typ != nil {
112 t := check.typ(typ)
113 if !isConstType(t) {
114 check.errorf(typ.Pos(), "invalid constant type %s", t)
115 obj.typ = Typ[Invalid]
116 return
118 obj.typ = t
121 // check initialization
122 var x operand
123 if init != nil {
124 check.expr(&x, init)
126 check.initConst(obj, &x)
129 func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
130 assert(obj.typ == nil)
132 if obj.visited {
133 obj.typ = Typ[Invalid]
134 return
136 obj.visited = true
138 // var declarations cannot use iota
139 assert(check.iota == nil)
141 // determine type, if any
142 if typ != nil {
143 obj.typ = check.typ(typ)
144 // We cannot spread the type to all lhs variables if there
145 // are more than one since that would mark them as checked
146 // (see Checker.objDecl) and the assignment of init exprs,
147 // if any, would not be checked.
149 // TODO(gri) If we have no init expr, we should distribute
150 // a given type otherwise we need to re-evalate the type
151 // expr for each lhs variable, leading to duplicate work.
154 // check initialization
155 if init == nil {
156 if typ == nil {
157 // error reported before by arityMatch
158 obj.typ = Typ[Invalid]
160 return
163 if lhs == nil || len(lhs) == 1 {
164 assert(lhs == nil || lhs[0] == obj)
165 var x operand
166 check.expr(&x, init)
167 check.initVar(obj, &x, "variable declaration")
168 return
171 if debug {
172 // obj must be one of lhs
173 found := false
174 for _, lhs := range lhs {
175 if obj == lhs {
176 found = true
177 break
180 if !found {
181 panic("inconsistent lhs")
185 // We have multiple variables on the lhs and one init expr.
186 // Make sure all variables have been given the same type if
187 // one was specified, otherwise they assume the type of the
188 // init expression values (was issue #15755).
189 if typ != nil {
190 for _, lhs := range lhs {
191 lhs.typ = obj.typ
195 check.initVars(lhs, []ast.Expr{init}, token.NoPos)
198 // underlying returns the underlying type of typ; possibly by following
199 // forward chains of named types. Such chains only exist while named types
200 // are incomplete.
201 func underlying(typ Type) Type {
202 for {
203 n, _ := typ.(*Named)
204 if n == nil {
205 break
207 typ = n.underlying
209 return typ
212 func (n *Named) setUnderlying(typ Type) {
213 if n != nil {
214 n.underlying = typ
218 func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*TypeName, alias bool) {
219 assert(obj.typ == nil)
221 // type declarations cannot use iota
222 assert(check.iota == nil)
224 if alias {
226 obj.typ = Typ[Invalid]
227 obj.typ = check.typExpr(typ, nil, append(path, obj))
229 } else {
231 named := &Named{obj: obj}
232 def.setUnderlying(named)
233 obj.typ = named // make sure recursive type declarations terminate
235 // determine underlying type of named
236 check.typExpr(typ, named, append(path, obj))
238 // The underlying type of named may be itself a named type that is
239 // incomplete:
241 // type (
242 // A B
243 // B *C
244 // C A
245 // )
247 // The type of C is the (named) type of A which is incomplete,
248 // and which has as its underlying type the named type B.
249 // Determine the (final, unnamed) underlying type by resolving
250 // any forward chain (they always end in an unnamed type).
251 named.underlying = underlying(named.underlying)
255 // check and add associated methods
256 // TODO(gri) It's easy to create pathological cases where the
257 // current approach is incorrect: In general we need to know
258 // and add all methods _before_ type-checking the type.
259 // See https://play.golang.org/p/WMpE0q2wK8
260 check.addMethodDecls(obj)
263 func (check *Checker) addMethodDecls(obj *TypeName) {
264 // get associated methods
265 methods := check.methods[obj.name]
266 if len(methods) == 0 {
267 return // no methods
269 delete(check.methods, obj.name)
271 // use an objset to check for name conflicts
272 var mset objset
274 // spec: "If the base type is a struct type, the non-blank method
275 // and field names must be distinct."
276 base, _ := obj.typ.(*Named) // nil if receiver base type is type alias
277 if base != nil {
278 if t, _ := base.underlying.(*Struct); t != nil {
279 for _, fld := range t.fields {
280 if fld.name != "_" {
281 assert(mset.insert(fld) == nil)
286 // Checker.Files may be called multiple times; additional package files
287 // may add methods to already type-checked types. Add pre-existing methods
288 // so that we can detect redeclarations.
289 for _, m := range base.methods {
290 assert(m.name != "_")
291 assert(mset.insert(m) == nil)
295 // type-check methods
296 for _, m := range methods {
297 // spec: "For a base type, the non-blank names of methods bound
298 // to it must be unique."
299 if m.name != "_" {
300 if alt := mset.insert(m); alt != nil {
301 switch alt.(type) {
302 case *Var:
303 check.errorf(m.pos, "field and method with the same name %s", m.name)
304 case *Func:
305 check.errorf(m.pos, "method %s already declared for %s", m.name, obj)
306 default:
307 unreachable()
309 check.reportAltDecl(alt)
310 continue
314 // type-check
315 check.objDecl(m, nil, nil)
317 // methods with blank _ names cannot be found - don't keep them
318 if base != nil && m.name != "_" {
319 base.methods = append(base.methods, m)
324 func (check *Checker) funcDecl(obj *Func, decl *declInfo) {
325 assert(obj.typ == nil)
327 // func declarations cannot use iota
328 assert(check.iota == nil)
330 sig := new(Signature)
331 obj.typ = sig // guard against cycles
332 fdecl := decl.fdecl
333 check.funcType(sig, fdecl.Recv, fdecl.Type)
334 if sig.recv == nil && obj.name == "init" && (sig.params.Len() > 0 || sig.results.Len() > 0) {
335 check.errorf(fdecl.Pos(), "func init must have no arguments and no return values")
336 // ok to continue
339 // function body must be type-checked after global declarations
340 // (functions implemented elsewhere have no body)
341 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil {
342 check.later(obj.name, decl, sig, fdecl.Body)
346 func (check *Checker) declStmt(decl ast.Decl) {
347 pkg := check.pkg
349 switch d := decl.(type) {
350 case *ast.BadDecl:
351 // ignore
353 case *ast.GenDecl:
354 var last *ast.ValueSpec // last ValueSpec with type or init exprs seen
355 for iota, spec := range d.Specs {
356 switch s := spec.(type) {
357 case *ast.ValueSpec:
358 switch d.Tok {
359 case token.CONST:
360 // determine which init exprs to use
361 switch {
362 case s.Type != nil || len(s.Values) > 0:
363 last = s
364 case last == nil:
365 last = new(ast.ValueSpec) // make sure last exists
368 // declare all constants
369 lhs := make([]*Const, len(s.Names))
370 for i, name := range s.Names {
371 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(iota)))
372 lhs[i] = obj
374 var init ast.Expr
375 if i < len(last.Values) {
376 init = last.Values[i]
379 check.constDecl(obj, last.Type, init)
382 check.arityMatch(s, last)
384 // spec: "The scope of a constant or variable identifier declared
385 // inside a function begins at the end of the ConstSpec or VarSpec
386 // (ShortVarDecl for short variable declarations) and ends at the
387 // end of the innermost containing block."
388 scopePos := s.End()
389 for i, name := range s.Names {
390 check.declare(check.scope, name, lhs[i], scopePos)
393 case token.VAR:
394 lhs0 := make([]*Var, len(s.Names))
395 for i, name := range s.Names {
396 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil)
399 // initialize all variables
400 for i, obj := range lhs0 {
401 var lhs []*Var
402 var init ast.Expr
403 switch len(s.Values) {
404 case len(s.Names):
405 // lhs and rhs match
406 init = s.Values[i]
407 case 1:
408 // rhs is expected to be a multi-valued expression
409 lhs = lhs0
410 init = s.Values[0]
411 default:
412 if i < len(s.Values) {
413 init = s.Values[i]
416 check.varDecl(obj, lhs, s.Type, init)
417 if len(s.Values) == 1 {
418 // If we have a single lhs variable we are done either way.
419 // If we have a single rhs expression, it must be a multi-
420 // valued expression, in which case handling the first lhs
421 // variable will cause all lhs variables to have a type
422 // assigned, and we are done as well.
423 if debug {
424 for _, obj := range lhs0 {
425 assert(obj.typ != nil)
428 break
432 check.arityMatch(s, nil)
434 // declare all variables
435 // (only at this point are the variable scopes (parents) set)
436 scopePos := s.End() // see constant declarations
437 for i, name := range s.Names {
438 // see constant declarations
439 check.declare(check.scope, name, lhs0[i], scopePos)
442 default:
443 check.invalidAST(s.Pos(), "invalid token %s", d.Tok)
446 case *ast.TypeSpec:
447 obj := NewTypeName(s.Name.Pos(), pkg, s.Name.Name, nil)
448 // spec: "The scope of a type identifier declared inside a function
449 // begins at the identifier in the TypeSpec and ends at the end of
450 // the innermost containing block."
451 scopePos := s.Name.Pos()
452 check.declare(check.scope, s.Name, obj, scopePos)
453 check.typeDecl(obj, s.Type, nil, nil, s.Assign.IsValid())
455 default:
456 check.invalidAST(s.Pos(), "const, type, or var declaration expected")
460 default:
461 check.invalidAST(d.Pos(), "unknown ast.Decl node %T", d)