mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Fixes #74076 Change-Id: Icc67b3d4e342f329584433bd1250c56ae8f5a73d Reviewed-on: https://go-review.googlesource.com/c/go/+/690635 Reviewed-by: Alan Donovan <adonovan@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Commit-Queue: Alan Donovan <adonovan@google.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
// Copyright 2021 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package noder
|
|
|
|
import (
|
|
"cmd/compile/internal/base"
|
|
"cmd/compile/internal/syntax"
|
|
"cmd/internal/src"
|
|
)
|
|
|
|
// A posMap handles mapping from syntax.Pos to src.XPos.
|
|
type posMap struct {
|
|
bases map[*syntax.PosBase]*src.PosBase
|
|
cache struct {
|
|
last *syntax.PosBase
|
|
base *src.PosBase
|
|
}
|
|
}
|
|
|
|
type poser interface{ Pos() syntax.Pos }
|
|
type ender interface{ End() syntax.Pos }
|
|
|
|
func (m *posMap) pos(p poser) src.XPos { return m.makeXPos(p.Pos()) }
|
|
|
|
func (m *posMap) makeXPos(pos syntax.Pos) src.XPos {
|
|
// Predeclared objects (e.g., the result parameter for error.Error)
|
|
// do not have a position.
|
|
if !pos.IsKnown() {
|
|
return src.NoXPos
|
|
}
|
|
|
|
posBase := m.makeSrcPosBase(pos.Base())
|
|
return base.Ctxt.PosTable.XPos(src.MakePos(posBase, pos.Line(), pos.Col()))
|
|
}
|
|
|
|
// makeSrcPosBase translates from a *syntax.PosBase to a *src.PosBase.
|
|
func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
|
|
// fast path: most likely PosBase hasn't changed
|
|
if m.cache.last == b0 {
|
|
return m.cache.base
|
|
}
|
|
|
|
b1, ok := m.bases[b0]
|
|
if !ok {
|
|
fn := b0.Filename()
|
|
absfn := trimFilename(b0)
|
|
|
|
if b0.IsFileBase() {
|
|
b1 = src.NewFileBase(fn, absfn)
|
|
} else {
|
|
// line directive base
|
|
p0 := b0.Pos()
|
|
p0b := p0.Base()
|
|
if p0b == b0 {
|
|
panic("infinite recursion in makeSrcPosBase")
|
|
}
|
|
p1 := src.MakePos(m.makeSrcPosBase(p0b), p0.Line(), p0.Col())
|
|
b1 = src.NewLinePragmaBase(p1, fn, absfn, b0.Line(), b0.Col())
|
|
}
|
|
if m.bases == nil {
|
|
m.bases = make(map[*syntax.PosBase]*src.PosBase)
|
|
}
|
|
m.bases[b0] = b1
|
|
}
|
|
|
|
// update cache
|
|
m.cache.last = b0
|
|
m.cache.base = b1
|
|
|
|
return b1
|
|
}
|