]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/gc/subr.go
all: merge dev.inline into master
[gostls13.git] / src / cmd / compile / internal / gc / subr.go
index 7d008dfa65527f9d020995bfa67cd84ac7d76ec7..6a5e1a478e6d4d572b7691d892cba6fd8d7ec5be 100644 (file)
@@ -7,6 +7,7 @@ package gc
 import (
        "bytes"
        "cmd/internal/obj"
+       "cmd/internal/src"
        "crypto/md5"
        "encoding/binary"
        "fmt"
@@ -20,8 +21,8 @@ import (
 )
 
 type Error struct {
-       lineno int32
-       msg    string
+       pos src.XPos
+       msg string
 }
 
 var errors []Error
@@ -39,24 +40,24 @@ func adderrorname(n *Node) {
                return
        }
        old := fmt.Sprintf("%v: undefined: %v\n", n.Line(), n.Left)
-       if len(errors) > 0 && errors[len(errors)-1].lineno == n.Lineno && errors[len(errors)-1].msg == old {
+       if len(errors) > 0 && errors[len(errors)-1].pos.Line() == n.Pos.Line() && errors[len(errors)-1].msg == old {
                errors[len(errors)-1].msg = fmt.Sprintf("%v: undefined: %v in %v\n", n.Line(), n.Left, n)
        }
 }
 
-func adderr(line int32, format string, args ...interface{}) {
+func adderr(pos src.XPos, format string, args ...interface{}) {
        errors = append(errors, Error{
-               lineno: line,
-               msg:    fmt.Sprintf("%v: %s\n", linestr(line), fmt.Sprintf(format, args...)),
+               pos: pos,
+               msg: fmt.Sprintf("%v: %s\n", linestr(pos), fmt.Sprintf(format, args...)),
        })
 }
 
-// byLineno sorts errors by lineno.
-type byLineno []Error
+// byPos sorts errors by source position.
+type byPos []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) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x byPos) Len() int           { return len(x) }
+func (x byPos) Less(i, j int) bool { return x[i].pos.Before(x[j].pos) }
+func (x byPos) 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,
 // and empties the errors array.
@@ -65,7 +66,7 @@ func flusherrors() {
        if len(errors) == 0 {
                return
        }
-       sort.Stable(byLineno(errors))
+       sort.Stable(byPos(errors))
        for i := 0; i < len(errors); i++ {
                if i == 0 || errors[i].msg != errors[i-1].msg {
                        fmt.Printf("%s", errors[i].msg)
@@ -85,49 +86,56 @@ func hcrash() {
        }
 }
 
-func linestr(line int32) string {
-       return Ctxt.Line(int(line))
+func linestr(pos src.XPos) string {
+       return Ctxt.PosTable.Pos(pos).String()
 }
 
 // lasterror keeps track of the most recently issued error.
 // It is used to avoid multiple error messages on the same
 // line.
 var lasterror struct {
-       syntax int32  // line of last syntax error
-       other  int32  // line of last non-syntax error
-       msg    string // error message of last non-syntax error
+       syntax src.XPos // source position of last syntax error
+       other  src.XPos // source position of last non-syntax error
+       msg    string   // error message of last non-syntax error
 }
 
-func yyerrorl(line int32, format string, args ...interface{}) {
+// sameline reports whether two positions a, b are on the same line.
+func sameline(a, b src.XPos) bool {
+       p := Ctxt.PosTable.Pos(a)
+       q := Ctxt.PosTable.Pos(b)
+       return p.Base() == q.Base() && p.Line() == q.Line()
+}
+
+func yyerrorl(pos src.XPos, format string, args ...interface{}) {
        msg := fmt.Sprintf(format, args...)
 
        if strings.HasPrefix(msg, "syntax error") {
                nsyntaxerrors++
                // only one syntax error per line, no matter what error
-               if lasterror.syntax == line {
+               if sameline(lasterror.syntax, pos) {
                        return
                }
-               lasterror.syntax = line
+               lasterror.syntax = pos
        } else {
                // only one of multiple equal non-syntax errors per line
                // (flusherrors shows only one of them, so we filter them
                // here as best as we can (they may not appear in order)
                // so that we don't count them here and exit early, and
                // then have nothing to show for.)
-               if lasterror.other == line && lasterror.msg == msg {
+               if sameline(lasterror.other, pos) && lasterror.msg == msg {
                        return
                }
-               lasterror.other = line
+               lasterror.other = pos
                lasterror.msg = msg
        }
 
-       adderr(line, "%s", msg)
+       adderr(pos, "%s", msg)
 
        hcrash()
        nerrors++
        if nsavederrors+nerrors >= 10 && Debug['e'] == 0 {
                flusherrors()
-               fmt.Printf("%v: too many errors\n", linestr(line))
+               fmt.Printf("%v: too many errors\n", linestr(pos))
                errorexit()
        }
 }
@@ -142,7 +150,7 @@ func Warn(fmt_ string, args ...interface{}) {
        hcrash()
 }
 
-func Warnl(line int32, fmt_ string, args ...interface{}) {
+func Warnl(line src.XPos, fmt_ string, args ...interface{}) {
        adderr(line, fmt_, args...)
        if Debug['m'] != 0 {
                flusherrors()
@@ -172,35 +180,7 @@ func Fatalf(fmt_ string, args ...interface{}) {
        errorexit()
 }
 
-func linehistpragma(file string) {
-       if Debug['i'] != 0 {
-               fmt.Printf("pragma %s at line %v\n", file, linestr(lexlineno))
-       }
-       Ctxt.AddImport(file)
-}
-
-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)
-}
-
-func linehistpop() {
-       if Debug['i'] != 0 {
-               fmt.Printf("end of import at line %v\n", linestr(lexlineno))
-       }
-       Ctxt.LineHist.Pop(int(lexlineno))
-}
-
-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)
-}
-
-func setlineno(n *Node) int32 {
+func setlineno(n *Node) src.XPos {
        lno := lineno
        if n != nil {
                switch n.Op {
@@ -214,10 +194,10 @@ func setlineno(n *Node) int32 {
                        fallthrough
 
                default:
-                       lineno = n.Lineno
-                       if lineno == 0 {
+                       lineno = n.Pos
+                       if !lineno.IsKnown() {
                                if Debug['K'] != 0 {
-                                       Warn("setlineno: line 0")
+                                       Warn("setlineno: unknown position (line 0)")
                                }
                                lineno = lno
                        }
@@ -348,7 +328,7 @@ func importdot(opkg *Pkg, pack *Node) {
 
        if n == 0 {
                // can't possibly be used - there were no symbols
-               yyerrorl(pack.Lineno, "imported and not used: %q", opkg.Path)
+               yyerrorl(pack.Pos, "imported and not used: %q", opkg.Path)
        }
 }
 
@@ -357,7 +337,7 @@ func nod(op Op, nleft *Node, nright *Node) *Node {
        n.Op = op
        n.Left = nleft
        n.Right = nright
-       n.Lineno = lineno
+       n.Pos = lineno
        n.Xoffset = BADWIDTH
        n.Orig = n
        switch op {
@@ -473,9 +453,9 @@ func nodbool(b bool) *Node {
 // treecopy recursively copies n, with the exception of
 // ONAME, OLITERAL, OTYPE, and non-iota ONONAME leaves.
 // Copies of iota ONONAME nodes are assigned the current
-// value of iota_. If lineno != 0, it sets the line number
-// of newly allocated nodes to lineno.
-func treecopy(n *Node, lineno int32) *Node {
+// value of iota_. If pos.IsKnown(), it sets the source
+// position of newly allocated nodes to pos.
+func treecopy(n *Node, pos src.XPos) *Node {
        if n == nil {
                return nil
        }
@@ -484,11 +464,11 @@ func treecopy(n *Node, lineno int32) *Node {
        default:
                m := *n
                m.Orig = &m
-               m.Left = treecopy(n.Left, lineno)
-               m.Right = treecopy(n.Right, lineno)
-               m.List.Set(listtreecopy(n.List.Slice(), lineno))
-               if lineno != 0 {
-                       m.Lineno = lineno
+               m.Left = treecopy(n.Left, pos)
+               m.Right = treecopy(n.Right, pos)
+               m.List.Set(listtreecopy(n.List.Slice(), pos))
+               if pos.IsKnown() {
+                       m.Pos = pos
                }
                if m.Name != nil && n.Op != ODCLFIELD {
                        Dump("treecopy", n)
@@ -503,8 +483,8 @@ func treecopy(n *Node, lineno int32) *Node {
                        // so that all the copies of this const definition
                        // don't have the same iota value.
                        m := *n
-                       if lineno != 0 {
-                               m.Lineno = lineno
+                       if pos.IsKnown() {
+                               m.Pos = pos
                        }
                        m.SetIota(iota_)
                        return &m
@@ -1706,21 +1686,12 @@ func structargs(tl *Type, mustname bool) []*Node {
 //     method - M func (t T)(), a TFIELD type struct
 //     newnam - the eventual mangled name of this function
 
-var genwrapper_linehistdone int = 0
-
 func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
        if false && Debug['r'] != 0 {
                fmt.Printf("genwrapper rcvrtype=%v method=%v newnam=%v\n", rcvr, method, newnam)
        }
 
-       lexlineno++
-       lineno = lexlineno
-       if genwrapper_linehistdone == 0 {
-               // All the wrappers can share the same linehist entry.
-               linehistpush("<autogenerated>")
-
-               genwrapper_linehistdone = 1
-       }
+       lineno = MakePos(src.NewFileBase("<autogenerated>", "<autogenerated>"), 1, 0)
 
        dclcontext = PEXTERN
        markdcl()
@@ -1993,10 +1964,10 @@ func Simsimtype(t *Type) EType {
        return et
 }
 
-func listtreecopy(l []*Node, lineno int32) []*Node {
+func listtreecopy(l []*Node, pos src.XPos) []*Node {
        var out []*Node
        for _, n := range l {
-               out = append(out, treecopy(n, lineno))
+               out = append(out, treecopy(n, pos))
        }
        return out
 }
@@ -2005,7 +1976,7 @@ func liststmt(l []*Node) *Node {
        n := nod(OBLOCK, nil, nil)
        n.List.Set(l)
        if len(l) != 0 {
-               n.Lineno = l[0].Lineno
+               n.Pos = l[0].Pos
        }
        return n
 }