mirror of
https://github.com/golang/go
synced 2024-11-26 05:48:05 -07:00
cmd/compile/internal/syntax: add PosBase.Trimmed
With types2, some syntax.PosBases need to be constructed from export data, which must only contain "trimmed" filenames (i.e., that they've already been made absolute and undergone -trimpath processing). However, it's not safe to apply trimming to a filename multiple times, and in general we can't distinguish trimmed from untrimmed filenames. This CL resolves this by adding a PosBase.Trimmed boolean so we can distinguish whether the associated filename has been trimmed yet. This is a bit hacky, but is the least bad solution I've come up with so far. This unblocks enabling -G=3 by default. Change-Id: I7383becfb704680a36f7603e3246af38b21f100b Reviewed-on: https://go-review.googlesource.com/c/go/+/343731 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Trust: Dan Scales <danscales@google.com> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
5045477be8
commit
ab9aaf46ee
@ -257,7 +257,7 @@ func (p *iimporter) posBaseAt(off uint64) *syntax.PosBase {
|
||||
return posBase
|
||||
}
|
||||
filename := p.stringAt(off)
|
||||
posBase := syntax.NewFileBase(filename)
|
||||
posBase := syntax.NewTrimmedFileBase(filename, true)
|
||||
p.posBaseCache[off] = posBase
|
||||
return posBase
|
||||
}
|
||||
|
@ -191,13 +191,23 @@ func (p *noder) errorAt(pos syntax.Pos, format string, args ...interface{}) {
|
||||
base.ErrorfAt(p.makeXPos(pos), format, args...)
|
||||
}
|
||||
|
||||
// TODO(gri) Can we eliminate fileh in favor of absFilename?
|
||||
func fileh(name string) string {
|
||||
return objabi.AbsFile("", name, base.Flag.TrimPath)
|
||||
}
|
||||
|
||||
func absFilename(name string) string {
|
||||
return objabi.AbsFile(base.Ctxt.Pathname, name, base.Flag.TrimPath)
|
||||
// trimFilename returns the "trimmed" filename of b, which is the
|
||||
// absolute filename after applying -trimpath processing. This
|
||||
// filename form is suitable for use in object files and export data.
|
||||
//
|
||||
// If b's filename has already been trimmed (i.e., because it was read
|
||||
// in from an imported package's export data), then the filename is
|
||||
// returned unchanged.
|
||||
func trimFilename(b *syntax.PosBase) string {
|
||||
filename := b.Filename()
|
||||
if !b.Trimmed() {
|
||||
dir := ""
|
||||
if b.IsFileBase() {
|
||||
dir = base.Ctxt.Pathname
|
||||
}
|
||||
filename = objabi.AbsFile(dir, filename, base.Flag.TrimPath)
|
||||
}
|
||||
return filename
|
||||
}
|
||||
|
||||
// noder transforms package syntax's AST into a Node tree.
|
||||
@ -1723,7 +1733,7 @@ func (p *noder) pragma(pos syntax.Pos, blankLine bool, text string, old syntax.P
|
||||
// (primarily misuse of linker flags), other files are not.
|
||||
// See golang.org/issue/23672.
|
||||
func isCgoGeneratedFile(pos syntax.Pos) bool {
|
||||
return strings.HasPrefix(filepath.Base(filepath.Clean(fileh(pos.Base().Filename()))), "_cgo_")
|
||||
return strings.HasPrefix(filepath.Base(trimFilename(pos.Base())), "_cgo_")
|
||||
}
|
||||
|
||||
// safeArg reports whether arg is a "safe" command-line argument,
|
||||
|
@ -45,8 +45,10 @@ func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
|
||||
b1, ok := m.bases[b0]
|
||||
if !ok {
|
||||
fn := b0.Filename()
|
||||
absfn := trimFilename(b0)
|
||||
|
||||
if b0.IsFileBase() {
|
||||
b1 = src.NewFileBase(fn, absFilename(fn))
|
||||
b1 = src.NewFileBase(fn, absfn)
|
||||
} else {
|
||||
// line directive base
|
||||
p0 := b0.Pos()
|
||||
@ -55,7 +57,7 @@ func (m *posMap) makeSrcPosBase(b0 *syntax.PosBase) *src.PosBase {
|
||||
panic("infinite recursion in makeSrcPosBase")
|
||||
}
|
||||
p1 := src.MakePos(m.makeSrcPosBase(p0b), p0.Line(), p0.Col())
|
||||
b1 = src.NewLinePragmaBase(p1, fn, fileh(fn), b0.Line(), b0.Col())
|
||||
b1 = src.NewLinePragmaBase(p1, fn, absfn, b0.Line(), b0.Col())
|
||||
}
|
||||
if m.bases == nil {
|
||||
m.bases = make(map[*syntax.PosBase]*src.PosBase)
|
||||
|
@ -194,16 +194,15 @@ func (pr *pkgReader) posBaseIdx(idx int) *src.PosBase {
|
||||
r := pr.newReader(relocPosBase, idx, syncPosBase)
|
||||
var b *src.PosBase
|
||||
|
||||
fn := r.string()
|
||||
absfn := r.string()
|
||||
filename := r.string()
|
||||
|
||||
if r.bool() {
|
||||
b = src.NewFileBase(fn, absfn)
|
||||
b = src.NewFileBase(filename, filename)
|
||||
} else {
|
||||
pos := r.pos0()
|
||||
line := r.uint()
|
||||
col := r.uint()
|
||||
b = src.NewLinePragmaBase(pos, fn, absfn, line, col)
|
||||
b = src.NewLinePragmaBase(pos, filename, filename, line, col)
|
||||
}
|
||||
|
||||
pr.posBases[idx] = b
|
||||
|
@ -109,15 +109,14 @@ func (pr *pkgReader2) posBaseIdx(idx int) *syntax.PosBase {
|
||||
var b *syntax.PosBase
|
||||
|
||||
filename := r.string()
|
||||
_ = r.string() // absolute file name
|
||||
|
||||
if r.bool() {
|
||||
b = syntax.NewFileBase(filename)
|
||||
b = syntax.NewTrimmedFileBase(filename, true)
|
||||
} else {
|
||||
pos := r.pos()
|
||||
line := r.uint()
|
||||
col := r.uint()
|
||||
b = syntax.NewLineBase(pos, filename, line, col)
|
||||
b = syntax.NewLineBase(pos, filename, true, line, col)
|
||||
}
|
||||
|
||||
pr.posBases[idx] = b
|
||||
|
@ -189,11 +189,7 @@ func (pw *pkgWriter) posBaseIdx(b *syntax.PosBase) int {
|
||||
w := pw.newWriter(relocPosBase, syncPosBase)
|
||||
w.p.posBasesIdx[b] = w.idx
|
||||
|
||||
// TODO(mdempsky): What exactly does "fileh" do anyway? Is writing
|
||||
// out both of these strings really the right thing to do here?
|
||||
fn := b.Filename()
|
||||
w.string(fn)
|
||||
w.string(fileh(fn))
|
||||
w.string(trimFilename(b))
|
||||
|
||||
if !w.bool(b.IsFileBase()) {
|
||||
w.pos(b)
|
||||
|
@ -146,11 +146,13 @@ func (p *parser) updateBase(pos Pos, tline, tcol uint, text string) {
|
||||
// If we have a column (//line filename:line:col form),
|
||||
// an empty filename means to use the previous filename.
|
||||
filename := text[:i-1] // lop off ":line"
|
||||
trimmed := false
|
||||
if filename == "" && ok2 {
|
||||
filename = p.base.Filename()
|
||||
trimmed = p.base.Trimmed()
|
||||
}
|
||||
|
||||
p.base = NewLineBase(pos, filename, line, col)
|
||||
p.base = NewLineBase(pos, filename, trimmed, line, col)
|
||||
}
|
||||
|
||||
func commentText(s string) string {
|
||||
|
@ -133,13 +133,19 @@ type PosBase struct {
|
||||
pos Pos
|
||||
filename string
|
||||
line, col uint32
|
||||
trimmed bool // whether -trimpath has been applied
|
||||
}
|
||||
|
||||
// NewFileBase returns a new PosBase for the given filename.
|
||||
// A file PosBase's position is relative to itself, with the
|
||||
// position being filename:1:1.
|
||||
func NewFileBase(filename string) *PosBase {
|
||||
base := &PosBase{MakePos(nil, linebase, colbase), filename, linebase, colbase}
|
||||
return NewTrimmedFileBase(filename, false)
|
||||
}
|
||||
|
||||
// NewTrimmedFileBase is like NewFileBase, but allows specifying Trimmed.
|
||||
func NewTrimmedFileBase(filename string, trimmed bool) *PosBase {
|
||||
base := &PosBase{MakePos(nil, linebase, colbase), filename, linebase, colbase, trimmed}
|
||||
base.pos.base = base
|
||||
return base
|
||||
}
|
||||
@ -149,8 +155,8 @@ func NewFileBase(filename string) *PosBase {
|
||||
// the comment containing the line directive. For a directive in a line comment,
|
||||
// that position is the beginning of the next line (i.e., the newline character
|
||||
// belongs to the line comment).
|
||||
func NewLineBase(pos Pos, filename string, line, col uint) *PosBase {
|
||||
return &PosBase{pos, filename, sat32(line), sat32(col)}
|
||||
func NewLineBase(pos Pos, filename string, trimmed bool, line, col uint) *PosBase {
|
||||
return &PosBase{pos, filename, sat32(line), sat32(col), trimmed}
|
||||
}
|
||||
|
||||
func (base *PosBase) IsFileBase() bool {
|
||||
@ -188,6 +194,13 @@ func (base *PosBase) Col() uint {
|
||||
return uint(base.col)
|
||||
}
|
||||
|
||||
func (base *PosBase) Trimmed() bool {
|
||||
if base == nil {
|
||||
return false
|
||||
}
|
||||
return base.trimmed
|
||||
}
|
||||
|
||||
func sat32(x uint) uint32 {
|
||||
if x > PosMax {
|
||||
return PosMax
|
||||
|
Loading…
Reference in New Issue
Block a user