src

Imports

Imports #

"bytes"
"fmt"
"io"

Constants & Variables

FileSymPrefix const #

FileSymPrefix is the linker symbol prefix that used to be used for linker pseudo-symbols representing file names.

const FileSymPrefix = "gofile.."

NoPos var #

NoPos is a valid unknown position.

var NoPos Pos

NoXPos var #

NoXPos is a valid unknown position.

var NoXPos XPos

PosDefaultLogue const #

const PosDefaultLogue PosXlogue = iota

PosDefaultStmt const #

It is expected that the front end or a phase in SSA will usually generate positions tagged with PosDefaultStmt, but note statement boundaries with PosIsStmt. Simple statements will have a single boundary; for loops with initialization may have one for their entry and one for their back edge (this depends on exactly how the loop is compiled; the intent is to provide a good experience to a user debugging a program; the goal is that a breakpoint set on the loop line fires both on entry and on iteration). Proper treatment of non-gofmt input with multiple simple statements on a single line is TBD. Optimizing compilation will move instructions around, and some of these will become known-bad as step targets for debugging purposes (examples: register spills and reloads; code generated into the entry block; invariant code hoisted out of loops) but those instructions will still have interesting positions for profiling purposes. To reflect this these positions will be changed to PosNotStmt. When the optimizer removes an instruction marked PosIsStmt; it should attempt to find a nearby instruction with the same line marked PosDefaultStmt to be the new statement boundary. I.e., the optimizer should make a best-effort to conserve statement boundary positions, and might be enhanced to note when a statement boundary is not conserved. Code cloning, e.g. loop unrolling or loop unswitching, is an exception to the conservation rule because a user running a debugger would expect to see breakpoints active in the copies of the code. In non-optimizing compilation there is still a role for PosNotStmt because of code generation into the entry block. PosIsStmt statement positions should be conserved. When code generation occurs any remaining default-marked positions are replaced with not-statement positions.

const PosDefaultStmt uint = iota

PosEpilogueBegin const #

const PosEpilogueBegin

PosIsStmt const #

const PosIsStmt

PosNotStmt const #

const PosNotStmt

PosPrologueEnd const #

const PosPrologueEnd

bogusLine const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const bogusLine = 1

colBits const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const colBits = *ast.BinaryExpr

colMax const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const colMax = *ast.BinaryExpr

colShift const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const colShift = *ast.BinaryExpr

isStmtBits const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const isStmtBits = 2

isStmtMask const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const isStmtMask = *ast.BinaryExpr

isStmtMax const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const isStmtMax = *ast.BinaryExpr

isStmtShift const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const isStmtShift = 0

lineBits const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const lineBits = 20

lineMax const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const lineMax = *ast.BinaryExpr

lineShift const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const lineShift = *ast.BinaryExpr

noPos var #

var noPos Pos

xlogueBits const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const xlogueBits = 2

xlogueMask const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const xlogueMask = *ast.BinaryExpr

xlogueMax const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const xlogueMax = *ast.BinaryExpr

xlogueShift const #

Layout constants: 20 bits for line, 8 bits for column, 2 for isStmt, 2 for pro/epilogue (If this is too tight, we can either make lico 64b wide, or we can introduce a tiered encoding where we remove column information as line numbers grow bigger; similar to what gcc does.) The bitfield order is chosen to make IsStmt be the least significant part of a position; its use is to communicate statement edges through instruction scrambling in code generation, not to impose an order. TODO: Prologue and epilogue are perhaps better handled as pseudo-ops for the assembler, because they have almost no interaction with other uses of the position.

const xlogueShift = *ast.BinaryExpr

Type Aliases

PosXlogue type #

type PosXlogue uint

lico type #

A lico is a compact encoding of a LIne and COlumn number.

type lico uint32

Structs

Pos struct #

A Pos encodes a source position consisting of a (line, column) number pair and a position base. A zero Pos is a ready to use "unknown" position (nil position base and zero line number). The (line, column) values refer to a position in a file independent of any position base ("absolute" file position). The position base is used to determine the "relative" position, that is the filename and line number relative to the position base. If the base refers to the current file, there is no difference between absolute and relative positions. If it refers to a //line directive, a relative position is relative to that directive. A position base in turn contains the position at which it was introduced in the current file.

type Pos struct {
base *PosBase
lico
}

PosBase struct #

A PosBase encodes a filename and base position. Typically, each file and line directive introduce a PosBase.

type PosBase struct {
pos Pos
filename string
absFilename string
line uint
col uint
inl int
fileIndex int
}

PosTable struct #

A PosTable tracks Pos -> XPos conversions and vice versa. Its zero value is a ready-to-use PosTable.

type PosTable struct {
baseList []*PosBase
indexMap map[*PosBase]int
nameMap map[string]int
}

XPos struct #

XPos is a more compact representation of Pos.

type XPos struct {
index int32
lico
}

Functions

AbsFilename method #

AbsFilename returns the absolute filename recorded with the base. If b == nil, the result is the empty string.

func (b *PosBase) AbsFilename() string

AbsFilename method #

AbsFilename() returns the absolute filename recorded with the position's base.

func (p Pos) AbsFilename() string

After method #

After reports whether the position p comes after q in the source. For positions with different bases, ordering is by base index.

func (p XPos) After(q XPos) bool

After method #

After reports whether the position p comes after q in the source. For positions in different files, ordering is by filename.

func (p Pos) After(q Pos) bool

AtColumn1 method #

AtColumn1 returns the same location but shifted to column 1.

func (p XPos) AtColumn1() XPos

Base method #

Base returns the position base.

func (p Pos) Base() *PosBase

Before method #

Before reports whether the position p comes before q in the source. For positions with different bases, ordering is by base index.

func (p XPos) Before(q XPos) bool

Before method #

Before reports whether the position p comes before q in the source. For positions in different files, ordering is by filename.

func (p Pos) Before(q Pos) bool

Col method #

func (x lico) Col() uint

Col method #

Col returns the column number recorded with the base. If b == nil, the result is 0.

func (b *PosBase) Col() uint

FileIndex method #

FileIndex returns the index of the base's absolute filename within its PosTable's FileTable. It panics if it hasn't been registered with a PosTable. If b == nil, the result is -1.

func (b *PosBase) FileIndex() int

FileIndex method #

FileIndex returns the file index of the position's base's absolute filename within the PosTable that it was registered.

func (p Pos) FileIndex() int

FileIndex method #

FileIndex returns a smallish non-negative integer corresponding to the file for this source position. Smallish is relative; it can be thousands large, but not millions.

func (p XPos) FileIndex() int32

FileTable method #

FileTable returns a slice of all files used to build this package.

func (t *PosTable) FileTable() []string

Filename method #

Filename returns the filename recorded with the base. If b == nil, the result is the empty string.

func (b *PosBase) Filename() string

Filename method #

Filename returns the name of the actual file containing this position.

func (p Pos) Filename() string

Format method #

Format formats a position as "filename:line" or "filename:line:column", controlled by the showCol flag and if the column is known (!= 0). For positions relative to line directives, the original position is shown as well, as in "filename:line[origfile:origline:origcolumn]" if showOrig is set.

func (p Pos) Format(showCol bool, showOrig bool) string

InliningIndex method #

InliningIndex returns the index into the global inlining tree recorded with the base. If b == nil or the base has not been inlined, the result is < 0.

func (b *PosBase) InliningIndex() int

IsKnown method #

IsKnown reports whether the position p is known. XPos.IsKnown() matches Pos.IsKnown() for corresponding positions.

func (p XPos) IsKnown() bool

IsKnown method #

IsKnown reports whether the position p is known. A position is known if it either has a non-nil position base, or a non-zero line number.

func (p Pos) IsKnown() bool

IsStmt method #

func (x lico) IsStmt() uint

Line method #

func (x lico) Line() uint

Line method #

Line returns the line number recorded with the base. If b == nil, the result is 0.

func (b *PosBase) Line() uint

LineNumber method #

LineNumber returns a string for the line number, "?" if it is not known.

func (p XPos) LineNumber() string

LineNumber method #

func (p Pos) LineNumber() string

LineNumberHTML method #

func (p XPos) LineNumberHTML() string

LineNumberHTML method #

func (p Pos) LineNumberHTML() string

MakePos function #

MakePos creates a new Pos value with the given base, and (file-absolute) line and column.

func MakePos(base *PosBase, line uint, col uint) Pos

NewFileBase function #

NewFileBase returns a new *PosBase for a file with the given (relative and absolute) filenames.

func NewFileBase(filename string, absFilename string) *PosBase

NewInliningBase function #

NewInliningBase returns a copy of the orig PosBase with the given inlining index. If orig == nil, NewInliningBase panics.

func NewInliningBase(orig *PosBase, inlTreeIndex int) *PosBase

NewLinePragmaBase function #

NewLinePragmaBase returns a new *PosBase for a line directive of the form //line filename:line:col /*line filename:line:col at position pos.

func NewLinePragmaBase(pos Pos, filename string, absFilename string, line uint, col uint) *PosBase

Pos method #

Pos returns the position at which base is located. If b == nil, the result is the zero position.

func (b *PosBase) Pos() *Pos

Pos method #

Pos returns the corresponding Pos for the given p. If p cannot be translated via t, the function panics.

func (t *PosTable) Pos(p XPos) Pos

RelCol method #

RelCol returns the column number relative to the position's base.

func (p Pos) RelCol() uint

RelFilename method #

RelFilename returns the filename recorded with the position's base.

func (p Pos) RelFilename() string

RelLine method #

RelLine returns the line number relative to the position's base.

func (p Pos) RelLine() uint

SameFile method #

SameFile reports whether p and q are positions in the same file.

func (p XPos) SameFile(q XPos) bool

SameFileAndLine method #

SameFileAndLine reports whether p and q are positions on the same line in the same file.

func (p XPos) SameFileAndLine(q XPos) bool

SameLine method #

func (x lico) SameLine(y lico) bool

SetBase method #

SetBase sets the position base.

func (p *Pos) SetBase(base *PosBase)

String method #

func (p Pos) String() string

WithBogusLine method #

WithBogusLine returns a bogus line that won't match any recorded for the source code. Its use is to disrupt the statements within an infinite loop so that the debugger will not itself loop infinitely waiting for the line number to change. gdb chooses not to display the bogus line; delve shows it with a complaint, but the alternative behavior is to hang.

func (p XPos) WithBogusLine() XPos

WithDefaultStmt method #

WithDefaultStmt returns the same location with undetermined is_stmt

func (p XPos) WithDefaultStmt() XPos

WithIsStmt method #

WithIsStmt returns the same location to be marked with DWARF is_stmt=1

func (p XPos) WithIsStmt() XPos

WithNotStmt method #

WithNotStmt returns the same location to be marked with DWARF is_stmt=0

func (p XPos) WithNotStmt() XPos

WithXlogue method #

WithXlogue returns the same location but marked with DWARF function prologue/epilogue

func (p XPos) WithXlogue(x PosXlogue) XPos

WriteTo method #

WriteTo a position to w, formatted as Format does.

func (p Pos) WriteTo(w io.Writer, showCol bool, showOrig bool)

XPos method #

XPos returns the corresponding XPos for the given pos, adding pos to t if necessary.

func (t *PosTable) XPos(pos Pos) XPos

Xlogue method #

func (x lico) Xlogue() PosXlogue

atColumn1 method #

func (x lico) atColumn1() lico

baseIndex method #

func (t *PosTable) baseIndex(base *PosBase) int32

format function #

format formats a (filename, line, col) tuple as "filename:line" (showCol is false or col == 0) or "filename:line:column" (showCol is true and col != 0).

func format(w io.Writer, filename string, line uint, col uint, showCol bool)

formatstr function #

formatstr wraps format to return a string.

func formatstr(filename string, line uint, col uint, showCol bool) string

lineNumber method #

func (x lico) lineNumber() string

lineNumberHTML method #

func (x lico) lineNumberHTML() string

makeBogusLico function #

This is a not-position that will not be elided. Depending on the debugger (gdb or delve) it may or may not be displayed.

func makeBogusLico() lico

makeLico function #

func makeLico(line uint, col uint) lico

makeLicoRaw function #

func makeLicoRaw(line uint, col uint) lico

withDefaultStmt method #

withDefaultStmt returns a lico for the same location, with default isStmt

func (x lico) withDefaultStmt() lico

withIsStmt method #

withIsStmt returns a lico for the same location, tagged as definitely a statement

func (x lico) withIsStmt() lico

withNotStmt method #

withNotStmt returns a lico for the same location, but not a statement

func (x lico) withNotStmt() lico

withStmt method #

withStmt returns a lico for the same location with specified is_stmt attribute

func (x lico) withStmt(stmt uint) lico

withXlogue method #

withXlogue attaches a prologue/epilogue attribute to a lico

func (x lico) withXlogue(xlogue PosXlogue) lico

Generated with Arrow