1
2
3
4
5 package noder
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/syntax"
10 "cmd/internal/src"
11 )
12
13
14 type posMap struct {
15 bases map[*syntax.PosBase]*src.PosBase
16 cache struct {
17 last *syntax.PosBase
18 base *src.PosBase
19 }
20 }
21
22 type poser interface{ Pos() syntax.Pos }
23 type ender interface{ End() syntax.Pos }
24
25 func (m *posMap) pos(p poser) src.XPos { return m.makeXPos(p.Pos()) }
26 func (m *posMap) end(p ender) src.XPos { return m.makeXPos(p.End()) }
27
28 func (m *posMap) makeXPos(pos syntax.Pos) src.XPos {
29 if !pos.IsKnown() {
30
31 return src.NoXPos
32 }
33
34 posBase := m.makeSrcPosBase(pos.Base())
35 return base.Ctxt.PosTable.XPos(src.MakePos(posBase, pos.Line(), pos.Col()))
36 }
37
38
39 func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
40
41 if m.cache.last == b0 {
42 return m.cache.base
43 }
44
45 b1, ok := m.bases[b0]
46 if !ok {
47 fn := b0.Filename()
48 absfn := trimFilename(b0)
49
50 if b0.IsFileBase() {
51 b1 = src.NewFileBase(fn, absfn)
52 } else {
53
54 p0 := b0.Pos()
55 p0b := p0.Base()
56 if p0b == b0 {
57 panic("infinite recursion in makeSrcPosBase")
58 }
59 p1 := src.MakePos(m.makeSrcPosBase(p0b), p0.Line(), p0.Col())
60 b1 = src.NewLinePragmaBase(p1, fn, absfn, b0.Line(), b0.Col())
61 }
62 if m.bases == nil {
63 m.bases = make(map[*syntax.PosBase]*src.PosBase)
64 }
65 m.bases[b0] = b1
66 }
67
68
69 m.cache.last = b0
70 m.cache.base = b1
71
72 return b1
73 }
74
75 func (m *posMap) join(other *posMap) {
76 if m.bases == nil {
77 m.bases = make(map[*syntax.PosBase]*src.PosBase)
78 }
79 for k, v := range other.bases {
80 if m.bases[k] != nil {
81 base.Fatalf("duplicate posmap bases")
82 }
83 m.bases[k] = v
84 }
85 }
86
View as plain text