]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.inline] cmd/internal/src: make Pos implementation abstract
authorRobert Griesemer <gri@golang.org>
Thu, 8 Dec 2016 00:02:42 +0000 (16:02 -0800)
committerRobert Griesemer <gri@golang.org>
Thu, 8 Dec 2016 21:31:28 +0000 (21:31 +0000)
Adjust cmd/compile accordingly.

This will make it easier to replace the underlying implementation.

Change-Id: I33645850bb18c839b24785b6222a9e028617addb
Reviewed-on: https://go-review.googlesource.com/34133
Reviewed-by: David Lazar <lazard@golang.org>
36 files changed:
src/cmd/compile/fmt_test.go
src/cmd/compile/internal/amd64/ssa.go
src/cmd/compile/internal/arm/ssa.go
src/cmd/compile/internal/arm64/ssa.go
src/cmd/compile/internal/gc/alg.go
src/cmd/compile/internal/gc/bexport.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/fmt.go
src/cmd/compile/internal/gc/gsubr.go
src/cmd/compile/internal/gc/inl.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/noder.go
src/cmd/compile/internal/gc/order.go
src/cmd/compile/internal/gc/plive.go
src/cmd/compile/internal/gc/racewalk.go
src/cmd/compile/internal/gc/ssa.go
src/cmd/compile/internal/gc/subr.go
src/cmd/compile/internal/gc/typecheck.go
src/cmd/compile/internal/gc/util.go
src/cmd/compile/internal/mips/ssa.go
src/cmd/compile/internal/mips64/ssa.go
src/cmd/compile/internal/ppc64/ssa.go
src/cmd/compile/internal/s390x/ssa.go
src/cmd/compile/internal/ssa/compile.go
src/cmd/compile/internal/ssa/config.go
src/cmd/compile/internal/ssa/deadstore.go
src/cmd/compile/internal/ssa/func_test.go
src/cmd/compile/internal/ssa/html.go
src/cmd/compile/internal/ssa/nilcheck.go
src/cmd/compile/internal/ssa/regalloc.go
src/cmd/compile/internal/ssa/rewritegeneric.go
src/cmd/compile/internal/ssa/schedule.go
src/cmd/compile/internal/ssa/sparsemap.go
src/cmd/compile/internal/ssa/stackalloc.go
src/cmd/compile/internal/x86/ssa.go
src/cmd/internal/src/src.go

index 2490e37e2443a7a7bccc3d8c594c3abc871eccfb..1a648084f7d68752446d22124780a9dc8cb949ca 100644 (file)
@@ -654,7 +654,6 @@ var knownFormats = map[string]string{
        "cmd/compile/internal/syntax.token %q":            "",
        "cmd/compile/internal/syntax.token %s":            "",
        "cmd/internal/obj.As %v":                          "",
-       "cmd/internal/src.Pos %d":                         "",
        "error %v":                                        "",
        "float64 %.2f":                                    "",
        "float64 %.3f":                                    "",
index 3c997f20ae83bfd4659face71b417935fdf967be..98ea7cadf17dc1d925bd18ccc18d639de01aa461 100644 (file)
@@ -875,7 +875,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Reg = v.Args[0].Reg()
                gc.AddAux(&p.To, v)
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line.Line()==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
        case ssa.OpAMD64MOVLatomicload, ssa.OpAMD64MOVQatomicload:
index 5a69ed3c3bb9311f8ffe822535dae545d7288553..799d395208d8b9ce20edb6754c0bb0440c0dddac 100644 (file)
@@ -705,7 +705,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                gc.AddAux(&p.From, v)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = arm.REGTMP
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line.Line()==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
        case ssa.OpARMLoweredZero:
index 5670ef8e96ddd0edc298f5e1c7ca0d11e3a7975c..47976eb91b51d54f20e461a92a5451ae47197270 100644 (file)
@@ -690,7 +690,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                gc.AddAux(&p.From, v)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = arm64.REGTMP
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
        case ssa.OpVarDef:
index 8113710e3983742d588f3da4ba2dbd52d5ba01ae..50b75aa09fdb09cb3ba0a21ecf3205ff0bc37c15 100644 (file)
@@ -4,7 +4,10 @@
 
 package gc
 
-import "fmt"
+import (
+       "cmd/internal/src"
+       "fmt"
+)
 
 // AlgKind describes the kind of algorithms used for comparing and
 // hashing a Type.
@@ -186,7 +189,7 @@ func genhash(sym *Sym, t *Type) {
                fmt.Printf("genhash %v %v\n", sym, t)
        }
 
-       lineno = 1 // less confusing than end of input
+       lineno = src.MakePos(1) // less confusing than end of input
        dclcontext = PEXTERN
        markdcl()
 
@@ -362,7 +365,7 @@ func geneq(sym *Sym, t *Type) {
                fmt.Printf("geneq %v %v\n", sym, t)
        }
 
-       lineno = 1 // less confusing than end of input
+       lineno = src.MakePos(1) // less confusing than end of input
        dclcontext = PEXTERN
        markdcl()
 
index 1da5b699a4f7f21d21e1ad8344c6de3144949df8..c87ab9fb139b83bcbb0778d714c838f6ab3f80c4 100644 (file)
@@ -591,7 +591,7 @@ func (p *exporter) pos(n *Node) {
 
 func fileLine(n *Node) (file string, line int) {
        if n != nil {
-               file, line = Ctxt.LineHist.AbsFileLine(int(n.Lineno))
+               file, line = Ctxt.LineHist.AbsFileLine(int(n.Lineno.Line()))
        }
        return
 }
index 460764af3a01fde70d1d6f8c6fb608efe2f63667..4f2254e689ad3671c99118807c441c77969443a8 100644 (file)
@@ -114,7 +114,7 @@ func testdclstack() {
 
 // redeclare emits a diagnostic about symbol s being redeclared somewhere.
 func redeclare(s *Sym, where string) {
-       if s.Lastlineno == 0 {
+       if !s.Lastlineno.IsKnown() {
                var tmp string
                if s.Origpkg != nil {
                        tmp = s.Origpkg.Path
@@ -288,7 +288,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
 // declare constants from grammar
 // new_name_list [[type] = expr_list]
 func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
-       lno := src.Pos(0) // default is to leave line number alone in listtreecopy
+       var lno src.Pos // default is to leave line number alone in listtreecopy
        if len(cl) == 0 {
                if t != nil {
                        yyerror("const declaration cannot have type without expression")
@@ -719,7 +719,7 @@ func checkembeddedtype(t *Type) {
 
        if t.IsPtr() || t.IsUnsafePtr() {
                yyerror("embedded type cannot be a pointer")
-       } else if t.Etype == TFORW && t.ForwardType().Embedlineno == 0 {
+       } else if t.Etype == TFORW && !t.ForwardType().Embedlineno.IsKnown() {
                t.ForwardType().Embedlineno = lineno
        }
 }
@@ -1355,7 +1355,7 @@ func checknowritebarrierrec() {
        visitBottomUp(xtop, func(list []*Node, recursive bool) {
                // Functions with write barriers have depth 0.
                for _, n := range list {
-                       if n.Func.WBLineno != 0 && n.Func.Pragma&Yeswritebarrierrec == 0 {
+                       if n.Func.WBLineno.IsKnown() && n.Func.Pragma&Yeswritebarrierrec == 0 {
                                c.best[n] = nowritebarrierrecCall{target: nil, depth: 0, lineno: n.Func.WBLineno}
                        }
                }
@@ -1373,7 +1373,7 @@ func checknowritebarrierrec() {
                                        // yeswritebarrierrec function.
                                        continue
                                }
-                               if n.Func.WBLineno == 0 {
+                               if !n.Func.WBLineno.IsKnown() {
                                        c.curfn = n
                                        c.visitcodelist(n.Nbody)
                                }
index fffce440bc859ea8e22c1c26be2c8b69767a8819..53889be531277552f28087926c3f8e79bb4eaea4 100644 (file)
@@ -283,8 +283,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
                fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
        }
 
-       if n.Lineno != 0 {
-               fmt.Fprintf(s, " l(%d)", n.Lineno)
+       if n.Lineno.IsKnown() {
+               fmt.Fprintf(s, " l(%d)", n.Lineno.Line())
        }
 
        if c == 0 && n.Xoffset != BADWIDTH {
index c2784cd6af06ca86d0c2c17618c281d6b4b4e88c..3a3effec2f54789b6af1e960cbc500fec4eb7c33 100644 (file)
@@ -40,12 +40,12 @@ func Prog(as obj.As) *obj.Prog {
        Clearp(pc)
        p.Link = pc
 
-       if lineno == 0 && Debug['K'] != 0 {
-               Warn("prog: line 0")
+       if !lineno.IsKnown() && Debug['K'] != 0 {
+               Warn("prog: unknown position (line 0)")
        }
 
        p.As = as
-       p.Lineno = int32(lineno) // TODO(gri) fix this
+       p.Lineno = int32(lineno.Line()) // TODO(gri) fix this
        return p
 }
 
index bdca1b1d766db5cd13592d1caa8acaeaf23bcc71..1fe25fa15e5fb391c39d0e4b9c47d60fe3c4c131 100644 (file)
@@ -1029,7 +1029,7 @@ func setlno(n *Node, lno src.Pos) {
        }
 
        // don't clobber names, unless they're freshly synthesized
-       if n.Op != ONAME || n.Lineno == 0 {
+       if n.Op != ONAME || !n.Lineno.IsKnown() {
                n.Lineno = lno
        }
 
index 4ed7f1c5dcb1d375c899e3ebd7ce3ad9781e13ae..0fdb862c28a8a980aa656f20f16a231a722daf55 100644 (file)
@@ -300,7 +300,7 @@ func Main() {
        blockgen = 1
        dclcontext = PEXTERN
        nerrors = 0
-       lexlineno = 1
+       lexlineno = src.MakePos(1)
 
        timings.Start("fe", "loadsys")
        loadsys()
@@ -320,11 +320,11 @@ func Main() {
                // Instead of converting EOF into '\n' in getc and count it as an extra line
                // for the line history to work, and which then has to be corrected elsewhere,
                // just add a line here.
-               lexlineno++
+               lexlineno = src.MakePos(lexlineno.Line() + 1)
                linehistpop()
        }
        timings.Stop()
-       timings.AddEvent(int64(lexlineno-lexlineno0), "lines")
+       timings.AddEvent(int64(lexlineno.Line()-lexlineno0.Line()), "lines")
 
        testdclstack()
        mkpackage(localpkg.Name) // final import not used checks
index 8d3babc544bd59491592d509ea2bf946d8d2ac1b..e52b0c7511ea174df8cb248388f4954a1ea69126 100644 (file)
@@ -22,7 +22,7 @@ func parseFile(filename string) {
        }
        defer src.Close()
 
-       p := noder{baseline: lexlineno}
+       p := noder{baseline: lexlineno.Line()}
        file, _ := syntax.Parse(src, p.error, p.pragma, 0) // errors are tracked via p.error
 
        p.file(file)
@@ -40,7 +40,7 @@ func parseFile(filename string) {
 
 // noder transforms package syntax's AST into a Nod tree.
 type noder struct {
-       baseline  src.Pos
+       baseline  int32
        linknames []int // tracks //go:linkname lines
 }
 
@@ -50,7 +50,7 @@ func (p *noder) file(file *syntax.File) {
 
        xtop = append(xtop, p.decls(file.DeclList)...)
 
-       lexlineno = p.baseline + src.Pos(file.Lines) - 1
+       lexlineno = src.MakePos(p.baseline + int32(file.Lines) - 1)
        lineno = lexlineno
 }
 
@@ -231,7 +231,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
                yyerror("can only use //go:noescape with external func implementations")
        }
        f.Func.Pragma = pragma
-       lineno = p.baseline + src.Pos(fun.EndLine) - 1
+       lineno = src.MakePos(p.baseline + int32(fun.EndLine) - 1)
        f.Func.Endlineno = lineno
 
        funcbody(f)
@@ -357,14 +357,14 @@ func (p *noder) expr(expr syntax.Expr) *Node {
                        l[i] = p.wrapname(expr.ElemList[i], e)
                }
                n.List.Set(l)
-               lineno = p.baseline + src.Pos(expr.EndLine) - 1
+               lineno = src.MakePos(p.baseline + int32(expr.EndLine) - 1)
                return n
        case *syntax.KeyValueExpr:
                return p.nod(expr, OKEY, p.expr(expr.Key), p.wrapname(expr.Value, p.expr(expr.Value)))
        case *syntax.FuncLit:
                closurehdr(p.typeExpr(expr.Type))
                body := p.stmts(expr.Body)
-               lineno = p.baseline + src.Pos(expr.EndLine) - 1
+               lineno = src.MakePos(p.baseline + int32(expr.EndLine) - 1)
                return p.setlineno(expr, closurebody(body))
        case *syntax.ParenExpr:
                return p.nod(expr, OPAREN, p.expr(expr.X), nil)
@@ -986,12 +986,12 @@ func (p *noder) nod(orig syntax.Node, op Op, left, right *Node) *Node {
 }
 
 func (p *noder) setlineno(src_ syntax.Node, dst *Node) *Node {
-       l := src.Pos(src_.Line())
+       l := src_.Line()
        if l == 0 {
                // TODO(mdempsky): Shouldn't happen. Fix package syntax.
                return dst
        }
-       dst.Lineno = p.baseline + l - 1
+       dst.Lineno = src.MakePos(p.baseline + int32(l) - 1)
        return dst
 }
 
@@ -999,24 +999,24 @@ func (p *noder) lineno(n syntax.Node) {
        if n == nil {
                return
        }
-       l := src.Pos(n.Line())
+       l := n.Line()
        if l == 0 {
                // TODO(mdempsky): Shouldn't happen. Fix package syntax.
                return
        }
-       lineno = p.baseline + l - 1
+       lineno = src.MakePos(p.baseline + int32(l) - 1)
 }
 
 func (p *noder) error(err error) {
        line := p.baseline
        var msg string
        if err, ok := err.(syntax.Error); ok {
-               line += src.Pos(err.Line) - 1
+               line += int32(err.Line) - 1
                msg = err.Msg
        } else {
                msg = err.Error()
        }
-       yyerrorl(line, "%s", msg)
+       yyerrorl(src.MakePos(line), "%s", msg)
 }
 
 func (p *noder) pragma(pos, line int, text string) syntax.Pragma {
@@ -1039,7 +1039,7 @@ func (p *noder) pragma(pos, line int, text string) syntax.Pragma {
                if n <= 0 {
                        break
                }
-               lexlineno = p.baseline + src.Pos(line)
+               lexlineno = src.MakePos(p.baseline + int32(line))
                linehistupdate(text[5:i], n)
 
        case strings.HasPrefix(text, "go:linkname "):
index e3d65e5e9df1a510e458c56e94b22bf256d4932e..433a89d0d1b83ad8b22354625f0abf54706f7aaa 100644 (file)
@@ -5,6 +5,7 @@
 package gc
 
 import (
+       "cmd/internal/src"
        "fmt"
 )
 
@@ -510,7 +511,7 @@ func orderstmt(n *Node, order *Order) {
 
                n.Left = orderexpr(n.Left, order, nil)
                n.Left = ordersafeexpr(n.Left, order)
-               tmp1 := treecopy(n.Left, 0)
+               tmp1 := treecopy(n.Left, src.Pos{})
                if tmp1.Op == OINDEXMAP {
                        tmp1.Etype = 0 // now an rvalue not an lvalue
                }
index a6f3735bdfb33d85ac7784f353c000ebb382d505..4cb829cc734cd1461b49cd1c0ad1f41fe45eadae 100644 (file)
@@ -1254,7 +1254,7 @@ func livenessepilogue(lv *Liveness) {
                                                if !n.Name.Needzero {
                                                        n.Name.Needzero = true
                                                        if debuglive >= 1 {
-                                                               Warnl(src.Pos(p.Lineno), "%v: %L is ambiguously live", Curfn.Func.Nname, n)
+                                                               Warnl(src.MakePos(p.Lineno), "%v: %L is ambiguously live", Curfn.Func.Nname, n)
                                                        }
                                                }
                                        }
@@ -1345,7 +1345,7 @@ func livenessepilogue(lv *Liveness) {
                                                }
                                                n := lv.vars[j]
                                                if n.Class != PPARAM {
-                                                       yyerrorl(src.Pos(p.Lineno), "internal error: %v %L recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, n, p.Pc)
+                                                       yyerrorl(src.MakePos(p.Lineno), "internal error: %v %L recorded as live on entry, p.Pc=%v", Curfn.Func.Nname, n, p.Pc)
                                                }
                                        }
                                }
index bfb82b91b22d84d487a0e87088568c764cd152a2..f4a02f355308256b1f51661ba2623959a13e9fea 100644 (file)
@@ -5,6 +5,7 @@
 package gc
 
 import (
+       "cmd/internal/src"
        "fmt"
        "strings"
 )
@@ -495,7 +496,7 @@ func callinstr(np **Node, init *Nodes, wr int, skip int) bool {
                        *np = n
                }
 
-               n = treecopy(n, 0)
+               n = treecopy(n, src.Pos{})
                makeaddable(n)
                var f *Node
                if flag_msan {
index 8df8adee59a812b1a2648cd81f0ffc595ae995f0..ae0f49bd6392a9b96627830be875254f0fabc91b 100644 (file)
@@ -54,7 +54,7 @@ func buildssa(fn *Node) *ssa.Func {
                s.noWB = true
        }
        defer func() {
-               if s.WBLineno != 0 {
+               if s.WBLineno.IsKnown() {
                        fn.Func.WBLineno = s.WBLineno
                }
        }()
@@ -332,12 +332,12 @@ func (s *state) endBlock() *ssa.Block {
 
 // pushLine pushes a line number on the line number stack.
 func (s *state) pushLine(line src.Pos) {
-       if line == 0 {
+       if !line.IsKnown() {
                // the frontend may emit node with line number missing,
                // use the parent line number in this case.
                line = s.peekLine()
                if Debug['K'] != 0 {
-                       Warn("buildssa: line 0")
+                       Warn("buildssa: unknown position (line 0)")
                }
        }
        s.line = append(s.line, line)
@@ -3263,7 +3263,7 @@ func canSSAType(t *Type) bool {
 func (s *state) exprPtr(n *Node, bounded bool, lineno src.Pos) *ssa.Value {
        p := s.expr(n)
        if bounded || n.NonNil {
-               if s.f.Config.Debug_checknil() && lineno > 1 {
+               if s.f.Config.Debug_checknil() && lineno.Line() > 1 {
                        s.f.Config.Warnl(lineno, "removed nil check")
                }
                return p
@@ -3426,7 +3426,7 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line src.Pos, righ
        if s.noWB {
                s.Error("write barrier prohibited")
        }
-       if s.WBLineno == 0 {
+       if !s.WBLineno.IsKnown() {
                s.WBLineno = left.Line
        }
 
@@ -3467,7 +3467,7 @@ func (s *state) insertWBstore(t *Type, left, right *ssa.Value, line src.Pos, ski
        if s.noWB {
                s.Error("write barrier prohibited")
        }
-       if s.WBLineno == 0 {
+       if !s.WBLineno.IsKnown() {
                s.WBLineno = left.Line
        }
        s.storeTypeScalars(t, left, right, skip)
index 49bb92beacc7a5c8580af157e737f05ce9c94645..f4a5cc97d914789bccc42482d7e7bb7231b9769f 100644 (file)
@@ -56,7 +56,7 @@ func adderr(line src.Pos, format string, args ...interface{}) {
 type byLineno []Error
 
 func (x byLineno) Len() int           { return len(x) }
-func (x byLineno) Less(i, j int) bool { return x[i].lineno < x[j].lineno }
+func (x byLineno) Less(i, j int) bool { return x[i].lineno.Before(x[j].lineno) }
 func (x byLineno) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
 
 // flusherrors sorts errors seen so far by line number, prints them to stdout,
@@ -87,7 +87,7 @@ func hcrash() {
 }
 
 func linestr(line src.Pos) string {
-       return Ctxt.Line(int(line))
+       return Ctxt.Line(int(line.Line()))
 }
 
 // lasterror keeps track of the most recently issued error.
@@ -184,21 +184,21 @@ func linehistpush(file string) {
        if Debug['i'] != 0 {
                fmt.Printf("import %s at line %v\n", file, linestr(lexlineno))
        }
-       Ctxt.LineHist.Push(int(lexlineno), file)
+       Ctxt.LineHist.Push(int(lexlineno.Line()), file)
 }
 
 func linehistpop() {
        if Debug['i'] != 0 {
                fmt.Printf("end of import at line %v\n", linestr(lexlineno))
        }
-       Ctxt.LineHist.Pop(int(lexlineno))
+       Ctxt.LineHist.Pop(int(lexlineno.Line()))
 }
 
 func linehistupdate(file string, off int) {
        if Debug['i'] != 0 {
                fmt.Printf("line %s at line %v\n", file, linestr(lexlineno))
        }
-       Ctxt.LineHist.Update(int(lexlineno), file, off)
+       Ctxt.LineHist.Update(int(lexlineno.Line()), file, off)
 }
 
 func setlineno(n *Node) src.Pos {
@@ -216,9 +216,9 @@ func setlineno(n *Node) src.Pos {
 
                default:
                        lineno = n.Lineno
-                       if lineno == 0 {
+                       if !lineno.IsKnown() {
                                if Debug['K'] != 0 {
-                                       Warn("setlineno: line 0")
+                                       Warn("setlineno: unknown position (line 0)")
                                }
                                lineno = lno
                        }
@@ -488,7 +488,7 @@ func treecopy(n *Node, lineno src.Pos) *Node {
                m.Left = treecopy(n.Left, lineno)
                m.Right = treecopy(n.Right, lineno)
                m.List.Set(listtreecopy(n.List.Slice(), lineno))
-               if lineno != 0 {
+               if lineno.IsKnown() {
                        m.Lineno = lineno
                }
                if m.Name != nil && n.Op != ODCLFIELD {
@@ -504,7 +504,7 @@ func treecopy(n *Node, lineno src.Pos) *Node {
                        // so that all the copies of this const definition
                        // don't have the same iota value.
                        m := *n
-                       if lineno != 0 {
+                       if lineno.IsKnown() {
                                m.Lineno = lineno
                        }
                        m.SetIota(iota_)
@@ -1714,7 +1714,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
                fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
        }
 
-       lexlineno++
+       lexlineno = src.MakePos(lexlineno.Line() + 1)
        lineno = lexlineno
        if genwrapper_linehistdone == 0 {
                // All the wrappers can share the same linehist entry.
index 27bb6ed9548ae8c9faab9234333347c6bce2cdd3..8da07c4ccd57411902997dc0c7dc14636d35a781 100644 (file)
@@ -3548,7 +3548,7 @@ func copytype(n *Node, t *Type) {
        // Double-check use of type as embedded type.
        lno := lineno
 
-       if embedlineno != 0 {
+       if embedlineno.IsKnown() {
                lineno = embedlineno
                if t.IsPtr() || t.IsUnsafePtr() {
                        yyerror("embedded type cannot be a pointer")
@@ -3629,7 +3629,7 @@ func typecheckdef(n *Node) *Node {
        if n.Op == ONONAME {
                if !n.Diag {
                        n.Diag = true
-                       if n.Lineno != 0 {
+                       if n.Lineno.IsKnown() {
                                lineno = n.Lineno
                        }
 
index bb5cede5a60da75f700594c4aede4dacfa39ae01..adc8518bf450e4e41822c5a1c9dc71ad8b0816c6 100644 (file)
@@ -11,7 +11,7 @@ import (
 )
 
 func (n *Node) Line() string {
-       return Ctxt.LineHist.LineString(int(n.Lineno))
+       return Ctxt.LineHist.LineString(int(n.Lineno.Line()))
 }
 
 var atExitFuncs []func()
index aef1f90969b07f430d13bbb7910fcf703ac5a77b..15ff16aa128f3e91fd623cc6dde4b7d889f46b8f 100644 (file)
@@ -796,7 +796,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                gc.AddAux(&p.From, v)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = mips.REGTMP
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
        case ssa.OpMIPSFPFlagTrue,
index 1432c6ceea735dda7e082ad63c833246a50f47e6..d6c00d1a50031468f8bb4abbef5bb902ba47671d 100644 (file)
@@ -548,7 +548,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                gc.AddAux(&p.From, v)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = mips.REGTMP
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
        case ssa.OpVarDef:
index 8387692f860f76614ca869b60c6cb129171e3d26..3f360965655b03011fac67df67d6ece64e262ccf 100644 (file)
@@ -803,7 +803,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                gc.AddAux(&p.From, v)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = ppc64.REGTMP
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
 
index e2d3c2849ba1b79535d064ecdf228ea24bc03eb3..61bf228d09a8abfe6abb0d692b11545c86df2789 100644 (file)
@@ -570,7 +570,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                gc.AddAux(&p.From, v)
                p.To.Type = obj.TYPE_REG
                p.To.Reg = s390x.REGTMP
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
        case ssa.OpS390XMVC:
index b9ec7eb6b7bddf22b1d712f5812e24f9e12b2367..6fe731d1a3c6ddaf44f25358b039ae0be345d8af 100644 (file)
@@ -5,6 +5,7 @@
 package ssa
 
 import (
+       "cmd/internal/src"
        "fmt"
        "log"
        "os"
@@ -128,7 +129,7 @@ func (f *Func) dumpFile(phaseName string) {
 
        fi, err := os.Create(fname)
        if err != nil {
-               f.Config.Warnl(0, "Unable to create after-phase dump file %s", fname)
+               f.Config.Warnl(src.Pos{}, "Unable to create after-phase dump file %s", fname)
                return
        }
 
index 031925e2fdb6d7ff33b5a8fb67deb9c648bdde6c..3cb9d9edb068e39b8e8889e23bcd8f3324f9b199 100644 (file)
@@ -270,7 +270,7 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config
                c.hasGReg = true
                c.noDuffDevice = true
        default:
-               fe.Fatalf(0, "arch %s not implemented", arch)
+               fe.Fatalf(src.Pos{}, "arch %s not implemented", arch)
        }
        c.ctxt = ctxt
        c.optimize = optimize
@@ -310,7 +310,7 @@ func NewConfig(arch string, fe Frontend, ctxt *obj.Link, optimize bool) *Config
        if ev != "" {
                v, err := strconv.ParseInt(ev, 10, 64)
                if err != nil {
-                       fe.Fatalf(0, "Environment variable GO_SSA_PHI_LOC_CUTOFF (value '%s') did not parse as a number", ev)
+                       fe.Fatalf(src.Pos{}, "Environment variable GO_SSA_PHI_LOC_CUTOFF (value '%s') did not parse as a number", ev)
                }
                c.sparsePhiCutoff = uint64(v) // convert -1 to maxint, for never use sparse
        }
@@ -332,7 +332,7 @@ func (c *Config) Ctxt() *obj.Link         { return c.ctxt }
 func (c *Config) NewFunc() *Func {
        // TODO(khr): should this function take name, type, etc. as arguments?
        if c.curFunc != nil {
-               c.Fatalf(0, "NewFunc called without previous Free")
+               c.Fatalf(src.Pos{}, "NewFunc called without previous Free")
        }
        f := &Func{Config: c, NamedValues: map[LocalSlot][]*Value{}}
        c.curFunc = f
@@ -357,7 +357,7 @@ func (c *Config) logDebugHashMatch(evname, name string) {
                        var ok error
                        file, ok = os.Create(tmpfile)
                        if ok != nil {
-                               c.Fatalf(0, "Could not open hash-testing logfile %s", tmpfile)
+                               c.Fatalf(src.Pos{}, "Could not open hash-testing logfile %s", tmpfile)
                        }
                }
                c.logfiles[evname] = file
index 89ab17a4271e0d595141274a892172ee1da9544f..0a4862be94dfe5115fd9590b39c3755ae3f392e5 100644 (file)
@@ -4,6 +4,8 @@
 
 package ssa
 
+import "cmd/internal/src"
+
 // dse does dead-store elimination on the Function.
 // Dead stores are those which are unconditionally followed by
 // another store to the same location, with no intervening load.
@@ -111,7 +113,7 @@ func dse(f *Func) {
                                if sz > 0x7fffffff { // work around sparseMap's int32 value type
                                        sz = 0x7fffffff
                                }
-                               shadowed.set(v.Args[0].ID, int32(sz), 0)
+                               shadowed.set(v.Args[0].ID, int32(sz), src.Pos{})
                        }
                }
                // walk to previous store
index 7136d8fb08a1a446e8bf6ae022bf43f348ace32c..81f1c33cde8136b4b36a07aab32a6d1463f34197 100644 (file)
@@ -37,6 +37,7 @@ package ssa
 //                the parser can be used instead of Fun.
 
 import (
+       "cmd/internal/src"
        "fmt"
        "reflect"
        "testing"
@@ -154,7 +155,7 @@ func Fun(c *Config, entry string, blocs ...bloc) fun {
                blocks[bloc.name] = b
                for _, valu := range bloc.valus {
                        // args are filled in the second pass.
-                       values[valu.name] = b.NewValue0IA(0, valu.op, valu.t, valu.auxint, valu.aux)
+                       values[valu.name] = b.NewValue0IA(src.Pos{}, valu.op, valu.t, valu.auxint, valu.aux)
                }
        }
        // Connect the blocks together and specify control values.
@@ -428,12 +429,12 @@ func TestConstCache(t *testing.T) {
                Bloc("entry",
                        Valu("mem", OpInitMem, TypeMem, 0, nil),
                        Exit("mem")))
-       v1 := f.f.ConstBool(0, TypeBool, false)
-       v2 := f.f.ConstBool(0, TypeBool, true)
+       v1 := f.f.ConstBool(src.Pos{}, TypeBool, false)
+       v2 := f.f.ConstBool(src.Pos{}, TypeBool, true)
        f.f.freeValue(v1)
        f.f.freeValue(v2)
-       v3 := f.f.ConstBool(0, TypeBool, false)
-       v4 := f.f.ConstBool(0, TypeBool, true)
+       v3 := f.f.ConstBool(src.Pos{}, TypeBool, false)
+       v4 := f.f.ConstBool(src.Pos{}, TypeBool, true)
        if v3.AuxInt != 0 {
                t.Errorf("expected %s to have auxint of 0\n", v3.LongString())
        }
index 316fd2aa25412a878964665f558631baa2c2caae..355dc75e75f16088b8c3f2dadce461bf8660e985 100644 (file)
@@ -6,6 +6,7 @@ package ssa
 
 import (
        "bytes"
+       "cmd/internal/src"
        "fmt"
        "html"
        "io"
@@ -20,7 +21,7 @@ type HTMLWriter struct {
 func NewHTMLWriter(path string, logger Logger, funcname string) *HTMLWriter {
        out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
        if err != nil {
-               logger.Fatalf(0, "%v", err)
+               logger.Fatalf(src.Pos{}, "%v", err)
        }
        html := HTMLWriter{File: out, Logger: logger}
        html.start(funcname)
@@ -328,13 +329,13 @@ func (w *HTMLWriter) WriteColumn(title string, html string) {
 
 func (w *HTMLWriter) Printf(msg string, v ...interface{}) {
        if _, err := fmt.Fprintf(w.File, msg, v...); err != nil {
-               w.Fatalf(0, "%v", err)
+               w.Fatalf(src.Pos{}, "%v", err)
        }
 }
 
 func (w *HTMLWriter) WriteString(s string) {
        if _, err := w.File.WriteString(s); err != nil {
-               w.Fatalf(0, "%v", err)
+               w.Fatalf(src.Pos{}, "%v", err)
        }
 }
 
index eb2d297f802609ec94939f403dab304410a8914a..6345332ac1b350f574612d491c6e3a9a8ec6bc8d 100644 (file)
@@ -101,7 +101,7 @@ func nilcheckelim(f *Func) {
                                                // This is a redundant implicit nil check.
                                                // Logging in the style of the former compiler -- and omit line 1,
                                                // which is usually in generated code.
-                                               if f.Config.Debug_checknil() && v.Line > 1 {
+                                               if f.Config.Debug_checknil() && v.Line.Line() > 1 {
                                                        f.Config.Warnl(v.Line, "removed nil check")
                                                }
                                                v.reset(OpUnknown)
@@ -147,7 +147,7 @@ func nilcheckelim2(f *Func) {
                for i := len(b.Values) - 1; i >= 0; i-- {
                        v := b.Values[i]
                        if opcodeTable[v.Op].nilCheck && unnecessary.contains(v.Args[0].ID) {
-                               if f.Config.Debug_checknil() && int(v.Line) > 1 {
+                               if f.Config.Debug_checknil() && v.Line.Line() > 1 {
                                        f.Config.Warnl(v.Line, "removed nil check")
                                }
                                v.reset(OpUnknown)
index 9eecbdf57c09f9684f1dc2734df47e0d7b4fe1fa..db68dda4d95fc40c5899b8d57e69fd015ab194aa 100644 (file)
@@ -555,7 +555,7 @@ func (s *regAllocState) init(f *Func) {
                case "s390x":
                        // nothing to do, R10 & R11 already reserved
                default:
-                       s.f.Config.fe.Fatalf(0, "arch %s not implemented", s.f.Config.arch)
+                       s.f.Config.fe.Fatalf(src.Pos{}, "arch %s not implemented", s.f.Config.arch)
                }
        }
        if s.f.Config.nacl {
@@ -1912,13 +1912,13 @@ func (e *edgeState) setup(idx int, srcReg []endReg, dstReg []startReg, stacklive
 
        // Live registers can be sources.
        for _, x := range srcReg {
-               e.set(&e.s.registers[x.r], x.v.ID, x.c, false, 0) // don't care the line number of the source
+               e.set(&e.s.registers[x.r], x.v.ID, x.c, false, src.Pos{}) // don't care the line number of the source
        }
        // So can all of the spill locations.
        for _, spillID := range stacklive {
                v := e.s.orig[spillID]
                spill := e.s.values[v.ID].spill
-               e.set(e.s.f.getHome(spillID), v.ID, spill, false, 0) // don't care the line number of the source
+               e.set(e.s.f.getHome(spillID), v.ID, spill, false, src.Pos{}) // don't care the line number of the source
        }
 
        // Figure out all the destinations we need.
index 1a2eacccf80af1ad74a63f6af5f4343d7e9958f9..0d582436aee5384476b26218e363a2941edd12a8 100644 (file)
@@ -6526,7 +6526,7 @@ func rewriteValuegeneric_OpNilCheck(v *Value, config *Config) bool {
                return true
        }
        // match: (NilCheck (Load (OffPtr [c] (SP)) mem) mem)
-       // cond: mem.Op == OpStaticCall         && isSameSym(mem.Aux, "runtime.newobject")      && c == config.ctxt.FixedFrameSize() + config.RegSize   && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")
+       // cond: mem.Op == OpStaticCall         && isSameSym(mem.Aux, "runtime.newobject")      && c == config.ctxt.FixedFrameSize() + config.RegSize   && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")
        // result: (Invalid)
        for {
                v_0 := v.Args[0]
@@ -6546,14 +6546,14 @@ func rewriteValuegeneric_OpNilCheck(v *Value, config *Config) bool {
                if mem != v.Args[1] {
                        break
                }
-               if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")) {
+               if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")) {
                        break
                }
                v.reset(OpInvalid)
                return true
        }
        // match: (NilCheck (OffPtr (Load (OffPtr [c] (SP)) mem)) mem)
-       // cond: mem.Op == OpStaticCall         && isSameSym(mem.Aux, "runtime.newobject")      && c == config.ctxt.FixedFrameSize() + config.RegSize   && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")
+       // cond: mem.Op == OpStaticCall         && isSameSym(mem.Aux, "runtime.newobject")      && c == config.ctxt.FixedFrameSize() + config.RegSize   && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")
        // result: (Invalid)
        for {
                v_0 := v.Args[0]
@@ -6577,7 +6577,7 @@ func rewriteValuegeneric_OpNilCheck(v *Value, config *Config) bool {
                if mem != v.Args[1] {
                        break
                }
-               if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && int(v.Line) > 1, v, "removed nil check")) {
+               if !(mem.Op == OpStaticCall && isSameSym(mem.Aux, "runtime.newobject") && c == config.ctxt.FixedFrameSize()+config.RegSize && warnRule(config.Debug_checknil() && v.Line.Line() > 1, v, "removed nil check")) {
                        break
                }
                v.reset(OpInvalid)
index f2a89d82d833429bddc596bcb6a0bbcde982072d..69c5cccd73e2f5d8efc8942bd3d23ca300888323 100644 (file)
@@ -47,7 +47,7 @@ func (h ValHeap) Less(i, j int) bool {
                return c > 0 // higher score comes later.
        }
        if x.Line != y.Line { // Favor in-order line stepping
-               return x.Line > y.Line
+               return x.Line.After(y.Line)
        }
        if x.Op != OpPhi {
                if c := len(x.Args) - len(y.Args); c != 0 {
index 3bc4eb9d78c62d6032a450ff8f2c97723f4a2323..d2a07e2534042452506f10f1a1f5caafeaa1742a 100644 (file)
@@ -66,7 +66,7 @@ func (s *sparseMap) setBit(k ID, v uint) {
                s.dense[i].val |= 1 << v
                return
        }
-       s.dense = append(s.dense, sparseEntry{k, 1 << v, 0})
+       s.dense = append(s.dense, sparseEntry{k, 1 << v, src.Pos{}})
        s.sparse[k] = int32(len(s.dense)) - 1
 }
 
index dc2fd7d33b0af87ebd0c99edf66846882d381ec3..599dc934f1f2c07f16c3a143760e53c352fe209d 100644 (file)
@@ -6,7 +6,10 @@
 
 package ssa
 
-import "fmt"
+import (
+       "cmd/internal/src"
+       "fmt"
+)
 
 type stackAllocState struct {
        f *Func
@@ -37,7 +40,7 @@ func newStackAllocState(f *Func) *stackAllocState {
                return new(stackAllocState)
        }
        if s.f != nil {
-               f.Config.Fatalf(0, "newStackAllocState called without previous free")
+               f.Config.Fatalf(src.Pos{}, "newStackAllocState called without previous free")
        }
        return s
 }
index 21be63426a497c9178296b5b3784e6c2c6f26a24..52c3eebb20c97c6058f03fdb295c24567e163d19 100644 (file)
@@ -788,7 +788,7 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
                p.To.Type = obj.TYPE_MEM
                p.To.Reg = v.Args[0].Reg()
                gc.AddAux(&p.To, v)
-               if gc.Debug_checknil != 0 && v.Line > 1 { // v.Line==1 in generated wrappers
+               if gc.Debug_checknil != 0 && v.Line.Line() > 1 { // v.Line==1 in generated wrappers
                        gc.Warnl(v.Line, "generated nil check")
                }
        case ssa.Op386FCHS:
index 2c3aef9efe66313a14f05615a3dac62a6ef372f0..8691a9aa7493304da97dc2a75077f0acc772fcef 100644 (file)
@@ -5,7 +5,25 @@
 // Package src implements source positions.
 package src
 
+// Implementation note: This is a thin abstraction over
+// the historic representation of source positions via
+// global line numbers. The abstraction will make it
+// easier to replace this implementation, eventually.
+
 // A Pos represents a source position.
-// It is an index into the global line table, which
-// maps a Pos to a file name and source line number.
-type Pos int32
+// The zero value for a Pos is a valid unknown position.
+type Pos struct {
+       // line is an index into the global line table, which maps
+       // the corresponding Pos to a file name and source line number.
+       line int32
+}
+
+// MakePos creates a new Pos from a line index.
+// It requires intimate knowledge of the underlying
+// implementation and should be used with caution.
+func MakePos(line int32) Pos { return Pos{line} }
+
+func (p Pos) IsKnown() bool     { return p.line != 0 }
+func (p Pos) Line() int32       { return p.line }
+func (p Pos) Before(q Pos) bool { return p.line < q.line }
+func (p Pos) After(q Pos) bool  { return p.line > q.line }