2017-05-04 14:35:31 +00:00
|
|
|
package reader
|
|
|
|
|
|
|
|
import (
|
|
|
|
"debug/dwarf"
|
|
|
|
|
2020-03-20 17:23:10 +00:00
|
|
|
"github.com/go-delve/delve/pkg/dwarf/godwarf"
|
|
|
|
)
|
2019-06-17 16:51:29 +00:00
|
|
|
|
2020-03-20 17:23:10 +00:00
|
|
|
type Variable struct {
|
|
|
|
*godwarf.Tree
|
|
|
|
Depth int
|
2017-05-04 14:35:31 +00:00
|
|
|
}
|
|
|
|
|
2020-07-28 16:19:51 +00:00
|
|
|
// VariablesFlags specifies some configuration flags for the Variables function.
|
|
|
|
type VariablesFlags uint8
|
|
|
|
|
|
|
|
const (
|
|
|
|
VariablesOnlyVisible VariablesFlags = 1 << iota
|
|
|
|
VariablesSkipInlinedSubroutines
|
|
|
|
VariablesTrustDeclLine
|
|
|
|
)
|
|
|
|
|
2020-03-20 17:23:10 +00:00
|
|
|
// Variables returns a list of variables contained inside 'root'.
|
|
|
|
// If onlyVisible is true only variables visible at pc will be returned.
|
|
|
|
// If skipInlinedSubroutines is true inlined subroutines will be skipped
|
2020-07-28 16:19:51 +00:00
|
|
|
func Variables(root *godwarf.Tree, pc uint64, line int, flags VariablesFlags) []Variable {
|
|
|
|
return variablesInternal(nil, root, 0, pc, line, flags)
|
2017-05-04 14:35:31 +00:00
|
|
|
}
|
|
|
|
|
2020-07-28 16:19:51 +00:00
|
|
|
func variablesInternal(v []Variable, root *godwarf.Tree, depth int, pc uint64, line int, flags VariablesFlags) []Variable {
|
2020-03-20 17:23:10 +00:00
|
|
|
switch root.Tag {
|
|
|
|
case dwarf.TagInlinedSubroutine:
|
2020-07-28 16:19:51 +00:00
|
|
|
if flags&VariablesSkipInlinedSubroutines != 0 {
|
2020-03-20 17:23:10 +00:00
|
|
|
return v
|
2017-05-04 14:35:31 +00:00
|
|
|
}
|
2020-03-20 17:23:10 +00:00
|
|
|
fallthrough
|
|
|
|
case dwarf.TagLexDwarfBlock, dwarf.TagSubprogram:
|
2020-07-28 16:19:51 +00:00
|
|
|
if (flags&VariablesOnlyVisible == 0) || root.ContainsPC(pc) {
|
2020-03-20 17:23:10 +00:00
|
|
|
for _, child := range root.Children {
|
2020-07-28 16:19:51 +00:00
|
|
|
v = variablesInternal(v, child, depth+1, pc, line, flags)
|
2017-09-08 10:31:03 +00:00
|
|
|
}
|
2017-05-04 14:35:31 +00:00
|
|
|
}
|
2020-03-20 17:23:10 +00:00
|
|
|
return v
|
|
|
|
default:
|
2020-07-28 16:19:51 +00:00
|
|
|
o := 0
|
|
|
|
if root.Tag != dwarf.TagFormalParameter && (flags&VariablesTrustDeclLine != 0) {
|
|
|
|
// visibility for variables starts the line after declaration line,
|
|
|
|
// except for formal parameters, which are visible on the same line they
|
|
|
|
// are defined.
|
|
|
|
o = 1
|
|
|
|
}
|
|
|
|
if declLine, ok := root.Val(dwarf.AttrDeclLine).(int64); !ok || line >= int(declLine)+o {
|
2020-03-20 17:23:10 +00:00
|
|
|
return append(v, Variable{root, depth})
|
2017-05-04 14:35:31 +00:00
|
|
|
}
|
2020-03-20 17:23:10 +00:00
|
|
|
return v
|
2017-05-04 14:35:31 +00:00
|
|
|
}
|
|
|
|
}
|