return posBase
}
filename := p.stringAt(off)
- posBase := syntax.NewFileBase(filename)
+ posBase := syntax.NewTrimmedFileBase(filename, true)
p.posBaseCache[off] = posBase
return posBase
}
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.
// (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,
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()
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)
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
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
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)
// 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 {
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
}
// 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 {
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