switch op := n.Op; op {
case ODCL:
p.op(ODCL)
- p.pos(n)
+ p.pos(n.Left) // use declared variable's pos
p.sym(n.Left)
p.typ(n.Left.Type)
sym := p.qualifiedName()
typ := p.typ()
val := p.value(typ)
- importconst(p.imp, sym, idealType(typ), npos(pos, nodlit(val)))
+ importconst(pos, p.imp, sym, idealType(typ), val)
case aliasTag:
pos := p.pos()
n := newfuncnamel(pos, sym)
n.Type = sig
- // TODO(mdempsky): Stop clobbering n.Pos in declare.
- savedlineno := lineno
- lineno = pos
declare(n, PFUNC)
- lineno = savedlineno
p.funcList = append(p.funcList, n)
importlist = append(importlist, n)
// read underlying type
t0 := p.typ()
- // TODO(mdempsky): Stop clobbering n.Pos in declare.
- savedlineno := lineno
- lineno = pos
p.importtype(t, t0)
- lineno = savedlineno
// interfaces don't have associated methods
if t0.IsInterface() {
pkg = p.pkg()
}
f.Sym = pkg.Lookup(name)
+ // TODO(mdempsky): Need param position.
f.Nname = asTypesNode(newname(f.Sym))
}
p.bool()
}
pos := p.pos()
- lhs := dclname(p.sym())
+ lhs := npos(pos, dclname(p.sym()))
typ := typenod(p.typ())
return npos(pos, liststmt(variter([]*Node{lhs}, typ, nil))) // TODO(gri) avoid list creation
xfunc := p.nod(expr, ODCLFUNC, nil, nil)
xfunc.Func.SetIsHiddenClosure(Curfn != nil)
- xfunc.Func.Nname = newfuncname(nblank.Sym) // filled in by typecheckclosure
+ xfunc.Func.Nname = p.setlineno(expr, newfuncname(nblank.Sym)) // filled in by typecheckclosure
xfunc.Func.Nname.Name.Param.Ntype = xtype
xfunc.Func.Nname.Name.Defn = xfunc
}
}
-// redeclare emits a diagnostic about symbol s being redeclared somewhere.
-func redeclare(s *types.Sym, where string) {
+// redeclare emits a diagnostic about symbol s being redeclared at pos.
+func redeclare(pos src.XPos, s *types.Sym, where string) {
if !s.Lastlineno.IsKnown() {
- var tmp string
- if s.Origpkg != nil {
- tmp = s.Origpkg.Path
- } else {
- tmp = s.Pkg.Path
+ pkg := s.Origpkg
+ if pkg == nil {
+ pkg = s.Pkg
}
- pkgstr := tmp
- yyerror("%v redeclared %s\n"+
- "\tprevious declaration during import %q", s, where, pkgstr)
+ yyerrorl(pos, "%v redeclared %s\n"+
+ "\tprevious declaration during import %q", s, where, pkg.Path)
} else {
- line1 := lineno
- line2 := s.Lastlineno
+ prevPos := s.Lastlineno
// When an import and a declaration collide in separate files,
// present the import as the "redeclared", because the declaration
// is visible where the import is, but not vice versa.
// See issue 4510.
if s.Def == nil {
- line2 = line1
- line1 = s.Lastlineno
+ pos, prevPos = prevPos, pos
}
- yyerrorl(line1, "%v redeclared %s\n"+
- "\tprevious declaration at %v", s, where, linestr(line2))
+ yyerrorl(pos, "%v redeclared %s\n"+
+ "\tprevious declaration at %v", s, where, linestr(prevPos))
}
}
// named OLITERAL needs Name; most OLITERALs don't.
n.Name = new(Name)
}
- n.Pos = lineno
+
s := n.Sym
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
if !inimport && !typecheckok && s.Pkg != localpkg {
- yyerror("cannot declare name %v", s)
+ yyerrorl(n.Pos, "cannot declare name %v", s)
}
gen := 0
if ctxt == PEXTERN {
if s.Name == "init" {
- yyerror("cannot declare init - must be func")
+ yyerrorl(n.Pos, "cannot declare init - must be func")
}
if s.Name == "main" && localpkg.Name == "main" {
- yyerror("cannot declare main - must be func")
+ yyerrorl(n.Pos, "cannot declare main - must be func")
}
externdcl = append(externdcl, n)
} else {
if Curfn == nil && ctxt == PAUTO {
+ lineno = n.Pos
Fatalf("automatic outside function")
}
if Curfn != nil {
// functype will print errors about duplicate function arguments.
// Don't repeat the error here.
if ctxt != PPARAM && ctxt != PPARAMOUT {
- redeclare(s, "in this block")
+ redeclare(n.Pos, s, "in this block")
}
}
func importsym(pkg *types.Pkg, s *types.Sym, op Op) {
if asNode(s.Def) != nil && asNode(s.Def).Op != op {
pkgstr := fmt.Sprintf("during import %q", pkg.Path)
- redeclare(s, pkgstr)
+ redeclare(lineno, s, pkgstr)
}
}
return asNode(s.Def).Type
}
-// importconst declares symbol s as an imported constant with type t and value n.
+// importconst declares symbol s as an imported constant with type t and value val.
// pkg is the package being imported
-func importconst(pkg *types.Pkg, s *types.Sym, t *types.Type, n *Node) {
+func importconst(pos src.XPos, pkg *types.Pkg, s *types.Sym, t *types.Type, val Val) {
importsym(pkg, s, OLITERAL)
- n = convlit(n, t)
-
if asNode(s.Def) != nil { // TODO: check if already the same.
return
}
- if n.Op != OLITERAL {
- yyerror("expression must be a constant")
- return
- }
-
- if n.Sym != nil {
- n1 := *n
- n = &n1
- }
-
- n.Orig = newname(s)
+ n := npos(pos, nodlit(val))
+ n = convlit1(n, t, false, reuseOK)
n.Sym = s
declare(n, PEXTERN)
return
}
if my.Def != nil {
- lineno = pack.Pos
- redeclare(my, "as imported package name")
+ redeclare(pack.Pos, my, "as imported package name")
}
my.Def = asTypesNode(pack)
my.Lastlineno = pack.Pos
}
func (p *noder) declName(name *syntax.Name) *Node {
- // TODO(mdempsky): Set lineno?
- return dclname(p.name(name))
+ return p.setlineno(name, dclname(p.name(name)))
}
func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
name = nblank.Sym // filled in by typecheckfunc
}
- f.Func.Nname = newfuncname(name)
+ f.Func.Nname = p.setlineno(fun.Name, newfuncname(name))
f.Func.Nname.Name.Defn = f
f.Func.Nname.Name.Param.Ntype = t
s1 := lookup(s.Name)
if s1.Def != nil {
pkgerror := fmt.Sprintf("during import %q", opkg.Path)
- redeclare(s1, pkgerror)
+ redeclare(lineno, s1, pkgerror)
continue
}